2 место Работа с коллекциями. Парсинг, доноры, регистрации

evgen2208

Client
Регистрация
12.10.2016
Сообщения
130
Благодарностей
162
Баллы
43
Всем привет.

Статья в большей степени для не совсем новичков, а тех кто уже попробовал сам писать шаблоны и начинает осваивать с#.
Будет много букв и кода.

День когда я научился пользоваться лямбда-выражениями - был одним из лучших. Радости не было предела, мне казалось - всё, теперь все мои трудности позади.
Собрать регуляркой все совпадения в тексте, проверить на какое-то дополнительное условие, привести результат к нужному мне виду... И все это в пару строк кубика С#.

=> это так называемая ЛЯБМДА. Лямбда-выражение. Слева - что передаем, справа - куда.

Начнем, как водится с простого:
Есть некоторый зено-список:
1.jpg
Воспользуемся методом First(принимающим функцию типа bool) проверим некоторое условие

2.png
C#:
//получим первое четное число
project.Lists["test"].First(
    element //это имя для переменной обозначающей некоторый элемент данной коллекции
            //тип соответствует типу елементов в коллекции
    =>         //это называется лямбда выражением
    int.Parse(element)%2==0 //это функция условие которй мы проверяем.
            //int.Parse(element) - приводим элемент к типу int
            //%2==0-проверяем отстаток от деления на 2, что он равен 0.
    );

//пишут обычно так:
return project.Lists["test"].First(e=>int.Parse(e)==0);
Теперь применим лямбду к коллекции регулярок:

C#:
//найдем слова c буквой о
string inp ="как однажды жан звонарь городской стащил фонарь";
string pat = @"\w*[о]\w*";
var res =
Regex.Matches(inp,pat)     // мы получили коллекцию совпадений. что дальше??
    .Cast<Match>()        //особеность работы с регулярками - обязательно привести к типу.Match
    .Select(m=>m.Value);//select - команда выборки а в скобках наша лямбда
                        //мы получаем как раз значение регулярки.

return string.Join("|",res);//однажды|звонарь|городской|фонарь
Практическое применение:
получим результат страницы поиска в гугле:
C#:
string url = "https://www.google.ru/search?q="+"contact-us"+"&oq="+"contact-us"+"&num=100&start="+"0"+"&lr=lang_ru";

string get =
    ZennoPoster.HttpGet(url,"",@"utf-8",ZennoLab.InterfacesLibrary.Enums.Http.ResponceType.HeaderAndBody,30000,"",project.Profile.UserAgent,false,0,null,"",false);

if (get.Contains("200 OK")) return get;
И выпарсим из него все ссылки:
C#:
string html = project.Variables["codeResult"].Value; //html ответ страницы гугла
string pat = @"(?<=\!\-\-m\-\-.+?a href\="").+?(?="")";//шаблон поиска ссылок на стрнице

project.Lists["test"].AddRange(
    Regex.Matches(html,pat) //все
    .Cast<Match>()            //тоже
    .Select(m=>m.Value)        //самое
);
3.png
Итого у нас в зенно-списке нужные нам ссылки.
Сделаем то же самое, только через браузер, работая о всеми элементами коллекции HemlElementCollection.
Перейдем на страницу результатов поиска:
C#:
string key = "inurl:register регистрация на форуме";
instance.ActiveTab.Navigate(
"https://www.google.ru/search?q="+key+"&oq="+key+"&num=100&start="+"0"+"&lr=lang_ru");
instance.ActiveTab.WaitDownloading();
И также выпарсим ссылки. Но будем парсить только определенные результаты и попутно собирать другие данные (тексты ссылок)
C#:
var tab = instance.ActiveTab;

//HtmlElement h;//определим вспомогательную переменную - только для вызова подсказок.
//чтобы удобней было работать с лямбдами, объявим вспомогательную переменную, которую потом удалим
//прожект мейкер не видит типы параметров в делегатах, и приходится писать "вслепую" что совсем неудобно и медленно
//в процессе написания кода, в имени нужной нам переменной, для вызова подсказок указываем эту
//а потом удалим(иначе ошибка будет)

tab.FindElementsByTags("h3") //коллекция заголовков <h3></h3>
    .Where(h=>h.InnerText.Contains("егистрация"))//фильтруем ссылки по содержанию текста
    .Select(h=> //формируем формат получаемых данных
         h.InnerText +"{TAB}"+ h.ParentElement.GetAttribute("href")
    );
мы получили коллекцию строк формата "Текст результата поиска {tab} целевая страница"

Теперь перейдем к моей любимой коллекции:
List - список элементов некоторого типа. Типы могут быть почти любые, в том числе вложенные списки.
List<string> - список строк
List<int> - список чисел
List<HtmlElement> - список Html-элементов.

Списки я люблю за методы ForEach и IndexOf. ForEach - Аналог обычной конструкции foreach только удобнее использовать.
Почти все коллекции, наборы, массивы, можно привести к типу List методом ToList() и можно сразу проводить манипуляции с элементами.
4.png
Action отличается от функции тем, что ничего не возвращает. Просто применяет определенные команды к каждому элементу списка.
Начнем как всегда с простого:

C#:
int [] nums = {1,2,3,4,5,6,7,8};

//Выведем в лог четные числа:
nums.ToList() //приведем массив к списку
    .ForEach(e=> //переменная для каждого элемента
    {
        if(e%2==0) //проверяем условие четности
            project.SendInfoToLog(e.ToString());//выводим в лог
    }
);
Как это применить с пользой? Например добавим наши полученные ссылки результатов поиска в Зенно таблицу.
В зенно-таблицах к сожалению нет аналога AddRange для списков, по добавлению сразу нескольких строк. Будем это обходить:

C#:
var t = project.Tables["table"];//таблица ЗП
t.ColSeparator = "{TAB}"; // разделитель столбцов в строке

tab.FindElementsByTags("h3")
    .Where(h=>h.InnerText.Contains("егистрация"))//фильтруем ссылки с текстом о регистрации
    .Select(h=> //формируем формат получаемых данных
         h.InnerText +"{TAB}"+ h.ParentElement.GetAttribute("href")
    ) //весь код выше - уже был.
.ToList() //приводим нашу коллекцию к списку
.ForEach(s=>t.AddRow(s));//Action для каждого элемента
Профит:
5.png
Вернемся теперь к нашему предыдущему списку с урлами, и будем проверять все результаты на наличие там форм, которые нам интересны:
Переходим последовательно по списку урлов из списка "test" и осуществляем проверку:
C#:
var tab = instance.ActiveTab;

//HtmlElement f; //это помощник для вызова подсказок, потом удаляем

tab.FindElementsByTags("form")//собираем ВСЕ формы на странице
.ToList()//приводим к списку
.ForEach(f=>//в метод мы передаем переменную f (HtmlElement <form...></form>)
{
    if (f.Width>0&&_f.Height>0)
        {//форма видимая на странице, значит с ней можно работать

            f.FindChildrenByTags("input;label").ToList().ForEach(i=>
            {//берем всех потомков типа input и label

                if (Regex.IsMatch(i.OuterHtml,"(mail|pochta|почта|мейл|мэйл)"))
                {//еcть признаки указывающие что на форме присутствует поле для емейла

                    project.Lists["emailForms"].Add(project.Variables["url"].Value);//отмечаем сайт с формой на которй есть email
                    //простой путь понять что здесь могут быть тигры:
                    if (f.FindChildrenByTags("textarea").Count>0) //проверим на форме тег textarea
                        //отметим что сайт - с формой обратной связи или коментария
                        project.Lists["textAreaForms"].Add( project.Variables["url"].Value);
                    else if(Regex.IsMatch(f.InnerHtml,"capt(cha|ture)|robot|human"))//проверяем признаки капчи
                        project.Lists["captchaForms"].Add(project.Variables["url"].Value);//с капчей
                    else project.Lists["noCaptchaForms"].Add(project.Variables["url"].Value);//без капчи
                }
            }
            );
        }
});
кое что пропустили...
Если мы нашли 1 форму без капчи и с емейлом еще и с текстовой областью,
А на странице есть еще другая форма с капчей, то сайт добавится в оба списка, что не есть хорошо.
Надо будет это проверять потом, или предусмотреть сейчас.
По хорошему, нужно создать новый тип со свойствами int,string и где-то его хранить... Но это не наш выбор. Мы же про работу с коллекциями и лямбды.
будем хранить в списке строки вида:
"N|url" номер формы на странице|урл страницы.
И исправим многократное добавление сайта.

Поехали!
C#:
var tab = instance.ActiveTab;
//HtmlElement f; //помощник

List<HtmlElement> forms = tab.FindElementsByTags("form").ToList();

forms.ForEach(f=>//в лямбду мы передаем HtmlElement <form...></form>
{
    string NUrl = project.Variables["url"].Value;
    NUrl =  forms.IndexOf(f).ToString()+"|"+NUrl;
    if (f.Width>0&&f.Height>0)
        {//форма видимая на странице
            bool isMail=false;
            f.FindChildrenByTags("input;label").ToList().ForEach(i=>
            {//берем всех потомков типа input и label
   
                if (Regex.IsMatch(i.OuterHtml,"(mail|pochta|почта|мейл|мэйл)"))
                //еcть признаки указывающие что на форме присутствует поле для емейла
                    isMail=true;
   
            });
            if(isMail) project.Lists["emailForms"].Add(NUrl);//сайт с формой на которй есть email

            if (f.FindChildrenByTags("textarea").Count>0) //проверитм на форме тег textarea
                project.Lists["textAreaForms"].Add(NUrl); //сайт с формой обратной связи или коментария
       
            if(Regex.IsMatch(f.InnerHtml,"capt(cha|ure)|robot|human"))//проверяем признаки капчи
                project.Lists["captchaForms"].Add(NUrl);//с капчей
            else project.Lists["noCaptchaForms"].Add(NUrl);//без капчи
        }
});
Получили мы 4 списка:
список урлов с полем для почты.
список урлов с полем для текта.
список урлов с капчей/без капчи.

емайл+тект ария+нет капчи = очень интересно. Так и хочется заполнить и посмотреть: что же нам придет на почту... Но до этого нужно еще добраться.

Проверим полученные списки на интересные сайты. Помогут нам как всегда лямбды:
C#:
project.Lists["textAreaForms"]
        .Where(t //каждый элемент списка textAreaForms
                =>
                !project.Lists["captchaForms"].Contains(t)//не присутствует в списке captchaForms
                )
Теперь пройдемся по списку интересных сайтов с формами, и попытаемся заполнить, работая с коллекциями и списками.
Для начала получим из нашего NUrl отдельно номер и отдельно url
Делать это будем не абы как, в одну строку, а пойдем сложным - со списками и лямбдами.
поработаем со строкой как со списком символов. Наша задача - обучиться работе с коллекциями.

C#:
string NUrl = project.Lists["veryGood"].First();

List<char> nuList = NUrl.ToArray()//разбираем строку n|url по символам
    .ToList(); //и приводим к списку(все как обычно)
int N = int.Parse(
    nuList.Where(//выбираем только те символы в строке
    c=>nuList.IndexOf(c)<nuList.IndexOf('|')//у которых номер меньше разделителя
    ).First(//у нас вряд ли больше 9 форм на странице, поэтому выбираем только первый элемент
    ).ToString()//нужно привести char к string, чтобы получить int. :) увы
    );

//А для получения урла из Списка символов познакомимся с еще одним интересным методом
//Aggregate: у него два параметра на входе предыдущий элемент(точнее результат предыдущей итерации) и текущий.

string url = nuList.Where(//выбираем только те символы в строке
    c=>nuList.IndexOf(c)>nuList.IndexOf('|')//все что после разделителя
    ) //у нас сейчас - выборка символов, это еще не строка.
      // применим Агрегатную функцию:
    .Aggregate("",(bef,af)=>bef.ToString()+af.ToString());
//"" - начальное значение
//(bef,af) - предыдущий элемент, и следующий.
//bef.ToString()+af.ToString() - выражение. мы просто склеиваем символы в строку.
var tab = instance.ActiveTab;

tab.Navigate(url);
tab.WaitDownloading();
Чтобы приступить к заполнению форм, нужно немного подготовиться:

C#:
//то что будем заносить в поля ввода
//чем больше вариантов опишем, тем больше сможем успешно заполнить форм
string name = project.Profile.Name;
string lname = project.Profile.Surname;
string phone = project.Profile.Phone;
string email=project.Profile.Email;
string pass = project.Profile.Password;
string message="Hallo world! http://Hallo.world";
string login = project.Profile.Login;
string company = project.Profile.NickName;

//для каждого поля определим текст по которому будем определять элемент(регулярное выражение)
//желательно предварительно изучить с десяток разных форм на разных сайтах. Но и этого нам достаточно для примера.
string isName = "Name|Имя";//первым, т.к. name присутствует в outerHtml у всех инпутов
string isLname="Last(| )name|фамилия";
string isCompany="company|компани";
string isPhone="(tel(e|)|)(ph|f)one|телефон";
string isMessage="textarea";
string isSubject="subject|t(h|)em(e|a)|тема|заголовок";
string isMail="m(a|e)il|po(4|ch)ta|почт";//это всегда последним, т.к. email может случайно заполниться, а его обязательно указать верным
//соберем всё в список:
List<string> regs = new List<string>{
    isName,isLname,isCompany,isPhone,isMessage,isMail //isSubject осознанно не включаем в этот список
};
и формируем словарь:
Dictionary<string,string> regval = new Dictionary<string,string>();
regval.Add(isName,name);
regval.Add(isLname,lname);
regval.Add(isCompany,company);
regval.Add(isPhone,phone);
regval.Add(isMessage,message);
regval.Add(isSubject,subj);
regval.Add(isMail,mail);


//определим алгоритм идентификации поля ввода
Func<HtmlElement,string,bool> Check = (h,reg) =>
{
    bool output = false;//не найдено соответствий
    //текст где будем проверять наличие регулярки
    string outer = h.OuterHtml;                        //сам инпут
    var parent1 = h.ParentElement;                    //родитель
    var parent2= parent1.ParentElement;                //следующий родитель
    if(parent1.TagName="label")                     //всегда проверяем ругулярку в подписи
        outer+=parent1.OuterHtml;             
    if(parent2.TagName="label"||                    //и у второго родителя тоже
        parent2.FindChildrenByTags(input).Count<=1     //смотрим что не попал еще один инпут
        )                                             //что мы не ушли в область другого инпута
        outer+=parent2.OuterHtml;

    if(Regex.IsMatch(outer,reg,RegexOptions.IgnoreCase))
        return true; //нашли соответствие
};
//и процедуру ввода данных в поле
Action<HtmlElement,string> SetValue = (h,val) =>
{
    h.Focus();
    h.Click();
    h.SetValue("","Full",false,false);
    h.SetValue(val,"Full",false,false);
};
Теперь само заполнение формы выглядит совсем просто:
C#:
HtmlElement form = tab.FindElementByTag("form",N);
//HtmlElement i; //вызыватель подсказок
regs.ForEach(reg=>//для каждого регулярного выражения
{
    form.FindChildrenByTags("input;textarea").ToList().ForEach(i=>
    {
        if(i.GetAttribute("type") != "submit") //пропускаем кнопки
        {
            if(Check(i,reg)) //если совпало
                SetValue(i,regval[reg]);//заполняем
        }
    });
});
6.png 7.png
8.png

Как видно из последнего фото, даже если мы что-то не предусмотрели (поле subject) оно всеравно заполняется значением name.

Добавим пару штрихов:
C#:
//отметим все чекбоксы
form.FindChildrenByTags("input:checkbox").ToList()
    .ForEach(c=>c.SetValue("true","Full",false,false));

//отметим все селекты
form.FindChildrenByTags("select").ToList()
    .ForEach(sel=>
    {
        sel.Click();
        sel.SetValue(//выберем предполследний элемент селектов
            sel.FindChildrenByTags("option").ElementAt(sel.FindChildrenByTags("option").Count-1).InnerHtml
        ,"Middle",true,false);
    });
Наша форма заполнена и готова для отправки.
Скрипт нажатия на кнопку отправки предлагаю написать самостоятельно (собрать коллекцию тегов button и input:submit на форме, и Форычем кликнуть по всем).

Это не идеальный скрипт по обработке всех возможных форм. Во первых, мы пропустили обработку капч, а во вторых, ищем формы только с элементом textarea.

Преимуществом данного шаблона заключается то, что для обработки новых форм с полями не предусмотренными шаблоном - достаточно добавить новое регулярное выражение и значение которое вставлять в найденный элемент.
А также поправить под себя метод Check - чтобы например при первом совпадении по регулярке - переходить к следующему инпуту. В следующей части, в заполнении регистрационных форм мы это сделаем.

Перейдем к самой сложной части - Заполнению регистрационных форм. Здесь подход "лишь бы ушло на нужный адрес с нужной ссылкой" не сработает, важна точность.
Придется подумать, или посмотреть с десяток рег форм, чтобы собрать варианты полей которые на них бывают, и подобрать к ним регулярки. Тем, кто не умеет пользоваться реулярками - придется просто больше собрать пар чтоИщем-значение.
У нас уже есть таблица со ссылками на страницы регистрации. пройдемся по ней и посмотрим. Что там есть.

Наберем с десяток пар критерий-значение
C#:
string name = project.Profile.Name;
string isName = "Имя|name";
string lname = project.Profile.Surname;
string isLname="Last(| )name|фамилия";
string phone = "9991234567";//project.Profile.Phone;
string isPhone="(tel(e|)|)(ph|f)one|телефон";
string mail=project.Profile.Email;
string isMail="m(a|e)il|po(4|ch)ta|почт";
string pass = project.Profile.Password;
string isPass = "passw(or|)d|пароль";
string isConfirmPass = "confirm pass|pass confirm|подтв";
string login = project.Profile.Login;
string isLogin = "(nick|user)(|name)|login|логин";
string company = project.Profile.NickName;
string isCompany="company|компани";
string subj="Theme title";
string isSubject="subject|t(h|)em(e|a)|тема|заголовок";
//как всегда "всё в список"
List<string> regs = new List<string>{
    isName,isLname,isCompany,isPhone,isMail,isPass,isConfirmPass,isLogin
};
//и в словарь:
Dictionary<string,string> regval = new Dictionary<string,string>();
regval.Add(isName,name);
regval.Add(isLname,lname);
regval.Add(isCompany,company);
regval.Add(isPhone,phone);
regval.Add(isMail,mail);
regval.Add(isPass,pass);
regval.Add(isConfirmPass,pass);
regval.Add(isLogin,login);
Немного изменим процедуру определения соответствия поля:
Будем работать только с видимым текстом (placeholder для input и innerText для родителей).
C#:
Func<HtmlElement,string,bool> Check = (h,reg) =>
{
    bool output = false;//пока в начале не найдено соответствий
    //текст где будем проверять наличие регулярки
    string outer = h.GetAttribute("placeholder");    //сам инпут
    var parent1 = h.ParentElement;                    //родитель
    var parent2= parent1.ParentElement;                //следующий родитель
    if(parent1.FindChildrenByTags("input").Count==1) //проверяем что не ушли в область другого инпута
        outer+=parent1.InnerText;               
    if(parent2.FindChildrenByTags("input").Count==1)//у второго родителя тоже
        outer+=parent2.InnerText;                    //

    if(Regex.IsMatch(outer,reg,RegexOptions.IgnoreCase))
        output = true; //нашли соответствие
    return output;
};
Процедуру ввода данных не трогаем.

Найдем форму на странице:
C#:
HtmlElement form = instance.ActiveTab.FindElementsByTags("form")
    .Where(f=>f.Width>0&&f.Height>0//только видимая форма
        &&Regex.IsMatch(
            f.InnerText+//ищем в тексте формы
            //+в видимом тексте кнопок и сабмитов
            String.Join("",f.FindChildrenByTags("button;input:submit").Select(b=>b.GetValue()))
        ,"registr|sign up|создать|регистр",RegexOptions.IgnoreCase)
    ).First();
Отметим все чекбоксы и селекты:
C#:
//отметим все чекбоксы
form.FindChildrenByTags("input:checkbox").ToList()
    .ForEach(c=>c.SetValue("true","Full",false,false));

form.FindChildrenByTags("select").ToList()//отметим все селекты
    .ForEach(sel=>
    {
        sel.Click();
        sel.SetValue(//выберем предполследний элемент селектов
            sel.FindChildrenByTags("option").ElementAt(sel.FindChildrenByTags("option").Count-1).InnerHtml
        ,"Middle",true,false);
    });
Вот собственно и всё заполнение теперь:
C#:
form.FindChildrenByTags("input:text;input:password;input:email").ToList().ForEach(i=>
{
    bool find = false;
    if(!find&&i.GetAttribute("type") != "submit") //пропускаем кнопки
    {
        regs.ForEach(reg=>
        {
            i.Focus(); Thread.Sleep(100);
            if(!find&&Check(i,reg)) //если совпало
            {
                SetValue(i,regval[reg]);//заполняем
                find=true; //остальные пропускаем
            }
        });
    }
});
Проверим на практике:
9.png 10.png
И наш любимый Зеннолаб:
11.png

как видим заполнено именно то что мы и указывали. Date,Year у нас нет в словаре и списке регулярок, поэтому они пустые.

Что делать с капчей?
На самом деле, до конца решить все проблемы с формами регистрации мне не удалось. В реальном шаблоне, сайты сначала группируются по типам (на некоторых сайтах сначала нужно согласиться с правилами, потом только появляются поля формы, где-то поля объединены в датасеты и для двух полей одно описание - поле и подтверждение, там алгоритм функции Check отличается).

То же самое и с капчей. В этом плане гугл-рекапча даже легче остальных будет, штатный кубик очень хорошо справляется как с поиском капчи, так и с разгадыванием. Для остальных случаев нужно или под каждый вид капчи писать отдельный обработчик, или целиком отправлять скрин элемента с капчей в сервис разгадывания. Это не является темой данной статьи.

Надеюсь теперь многие ваши задачи будут решаться быстрее, когда научитесь работать с коллекциями.

Но для заполнения большинства форм регистраций, данный способ работает. Надо только продумать достаточно вариантов типов полей и подобрать к ним регулярки.
 
Тема статьи
Парсинг
Номер конкурса статей
Одиннадцатый конкурс статей

Вложения

Для запуска проектов требуется программа ZennoPoster или ZennoDroid.
Это основное приложение, предназначенное для выполнения автоматизированных шаблонов действий (ботов).
Подробнее...

Для того чтобы запустить шаблон, откройте нужную программу. Нажмите кнопку «Добавить», и выберите файл проекта, который хотите запустить.
Подробнее о том, где и как выполняется проект.

Последнее редактирование модератором:

Astraport

Client
Регистрация
01.05.2015
Сообщения
4 930
Благодарностей
4 329
Баллы
113
Респект! Техническая статья это всегда хорошо.
 
  • Спасибо
Реакции: evgen2208

Nike59

Client
Регистрация
05.08.2011
Сообщения
122
Благодарностей
121
Баллы
43
А я было начал печалиться из-за отсутствия статей для 11-го Конкурса, написанных на высоком техническом уровне. Мое уважение автору за новые идеи и фишки, а также за профессионализм.
 

russya

Client
Регистрация
08.07.2014
Сообщения
719
Благодарностей
77
Баллы
28
Крутая статья!! но много мест не понятных, надо глубже мне еще изучать с#
 
  • Спасибо
Реакции: evgen2208

che100

Client
Регистрация
18.04.2017
Сообщения
808
Благодарностей
499
Баллы
63
Ещё особо не вникал, но на первый взгляд пока это лучшее за сезон.
 
  • Спасибо
Реакции: evgen2208 и molotok

radv

Client
Регистрация
11.05.2015
Сообщения
3 670
Благодарностей
1 854
Баллы
113
Заметил одну особенность, как только начинаю углублять свои знания по теме, или переписывать свои проекты (улучшая код), то в конкурсе появляются хорошие статьи по теме.
 

Holy LSB

Client
Регистрация
04.07.2016
Сообщения
27
Благодарностей
12
Баллы
3
Заметил одну особенность, как только начинаю углублять свои знания по теме, или переписывать свои проекты (улучшая код), то в конкурсе появляются хорошие статьи по теме.
это называется Феномен Баадера-Майнхоф :D
 

radv

Client
Регистрация
11.05.2015
Сообщения
3 670
Благодарностей
1 854
Баллы
113
это называется Феномен Баадера-Майнхоф :D
Не важно как называется, главное чтобы полезное было. А то помню в детстве, я только книжку какую нибудь прочитаю, так через неделю-две, по ТВ фильм показывают по мотивам этой книжки. :D
 

lzlmrf

Client
Регистрация
14.08.2015
Сообщения
487
Благодарностей
148
Баллы
43
круто! спасибо, в закладки однозначно !
 

Alex1987

Client
Регистрация
21.06.2016
Сообщения
48
Благодарностей
6
Баллы
8
У меня не работает шаб, может каких то библиотек не хватает? Подскажи плиз, а то уже час жёстко *усь))
 

evgen2208

Client
Регистрация
12.10.2016
Сообщения
130
Благодарностей
162
Баллы
43
У меня не работает шаб, может каких то библиотек не хватает? Подскажи плиз, а то уже час жёстко *усь))
что за ошибка?
Библиотек нет никаких. Версия ЗП где-то полугодичной давности (не помню какая была), еще до хрома.
 

Alex1987

Client
Регистрация
21.06.2016
Сообщения
48
Благодарностей
6
Баллы
8
Сам не понимаю
 

Вложения

evgen2208

Client
Регистрация
12.10.2016
Сообщения
130
Благодарностей
162
Баллы
43

gevolushn

Известная личность
Регистрация
25.03.2019
Сообщения
518
Благодарностей
269
Баллы
63

Alex1987

Client
Регистрация
21.06.2016
Сообщения
48
Благодарностей
6
Баллы
8
Вот
 

Вложения

  • 143,6 КБ Просмотры: 667

evgen2208

Client
Регистрация
12.10.2016
Сообщения
130
Благодарностей
162
Баллы
43
нажми на это сообщение лога, откроется кубик с ошибкой.
там код закоментированный:
Код:
//урл для переход на страницу надо предварительно
//получить из таблицы в отдельном кубике
instance.ActiveTab.Navigate(
//вот сюда вставить    //project.Tables["table"].GetCell(1,2)
);
вместо строки
//вот сюда вставить //project.Tables["table"].GetCell(1,2)
вставляешь URL (получаешь из переменной в другом кубике, или в этом же)

project.Tables["table"].GetCell(1,n) вместо n-номер строки в таблице.
 
  • Спасибо
Реакции: eliadsonet и Alex1987

Zhekaz

Client
Регистрация
14.03.2016
Сообщения
101
Благодарностей
53
Баллы
28

Zedx

Client
Регистрация
12.06.2018
Сообщения
1 164
Благодарностей
809
Баллы
113
Спасибо за статью. Как раз собираюсь изучать C#, очень пригодится
 
  • Спасибо
Реакции: evgen2208

Stelsgrower

Client
Регистрация
21.12.2018
Сообщения
134
Благодарностей
62
Баллы
28
Единственная содержательная статья в 11-ом конкурсе.
 
  • Спасибо
Реакции: evgen2208

Asmus003

Client
Регистрация
25.03.2018
Сообщения
180
Благодарностей
61
Баллы
28
Крутая и полезная статья, автору респект и мой голос!)
 
  • Спасибо
Реакции: evgen2208

vikas2006

Client
Регистрация
10.05.2019
Сообщения
62
Благодарностей
1
Баллы
8
Хорошо пояснил, особенно для новичков в с#
 

kveldulv

Client
Регистрация
08.05.2011
Сообщения
45
Благодарностей
16
Баллы
8

alexgrand

Client
Регистрация
08.08.2014
Сообщения
14
Благодарностей
14
Баллы
3
Доброго времени. Ошибки:
991dece3-b929-4e1d-9449-898b737eb457
99ad46df-cf4e-41c7-86da-4ade1cf6438d
99ad46df-cf4e-41c7-86da-4ade1cf6438d
8579b1d3-409e-4e7b-a3cc-d2c216766960
 

evgen2208

Client
Регистрация
12.10.2016
Сообщения
130
Благодарностей
162
Баллы
43
Доброго времени. Ошибки:
991dece3-b929-4e1d-9449-898b737eb457
99ad46df-cf4e-41c7-86da-4ade1cf6438d
99ad46df-cf4e-41c7-86da-4ade1cf6438d
8579b1d3-409e-4e7b-a3cc-d2c216766960
кинь лучше скрин с логами(включать Окна->Лог), нормальное описание ошибки будет.
 

Tsuk15

Client
Регистрация
25.04.2017
Сообщения
102
Благодарностей
40
Баллы
28
Очень круто! Я как раз не понимал лямбда выражения и все планировал с этим разобраться. Огромное спасибо!
 

Tsuk15

Client
Регистрация
25.04.2017
Сообщения
102
Благодарностей
40
Баллы
28
И кстати, такой универсальный кубик для регистрации я тоже разрабатывал, только для о работы на запросах и сайты с рекапечей реально самые уязвимые:-)
 

TwistDanceR

Активный пользователь
Регистрация
30.05.2019
Сообщения
479
Благодарностей
200
Баллы
43
Код:
string url = project.Variables["URL"].Value;
string get =
    ZennoPoster.HttpGet(url,"",@"utf-8",ZennoLab.InterfacesLibrary.Enums.Http.ResponceType.HeaderAndBody,30000,"",project.Profile.UserAgent,false,0,null,"",false);
if (get.Contains("200 OK")) return get;

string html = project.Variables["tes1"].Value;
string regex = @"(?<=class""r""><a\ href="")[\w\W]*?(?="")";

project.Lists["Список 1"].AddRange(Regex.Matches(html,regex).Cast<Match>().Select(m=>m.Value));
Памагити. Не могу найти ошибку :( Не кладёт данные в список. Может у меня в Regex ошибка? Хотя вроде всё норм....

2019-06-14_11-55-03.png
 
Последнее редактирование:

evgen2208

Client
Регистрация
12.10.2016
Сообщения
130
Благодарностей
162
Баллы
43
Код:
string url = project.Variables["URL"].Value;
string get =
    ZennoPoster.HttpGet(url,"",@"utf-8",ZennoLab.InterfacesLibrary.Enums.Http.ResponceType.HeaderAndBody,30000,"",project.Profile.UserAgent,false,0,null,"",false);
if (get.Contains("200 OK")) return get;

string html = project.Variables["tes1"].Value;
string regex = @"(?<=class""r""><a\ href="")[\w\W]*?(?="")";

project.Lists["Список 1"].AddRange(Regex.Matches(html,regex).Cast<Match>().Select(m=>m.Value));
Памагити. Не могу найти ошибку :( Не кладёт данные в список. Может у меня в Regex ошибка? Хотя вроде всё норм....

Посмотреть вложение 39705
if (get.Contains("200 OK")) return get;
вот здесь выход из кубика, и дальше код не выполняется.


Код:
string url = project.Variables["URL"].Value;
string get =
    ZennoPoster.HttpGet(url,"",@"utf-8",ZennoLab.InterfacesLibrary.Enums.Http.ResponceType.HeaderAndBody,30000,"",project.Profile.UserAgent,false,0,null,"",false);
if (get.Contains("200 OK"))
     project.Variables["tes1"].Value= get; //воттак надо в вашем случае

string html = project.Variables["tes1"].Value;
string regex = @"(?<=class""r""><a\ href="")[\w\W]*?(?="")";
project.Lists["Список 1"].AddRange(Regex.Matches(html,regex).Cast<Match>().Select(m=>m.Value));
 
  • Спасибо
Реакции: TwistDanceR

temass

Client
Регистрация
06.06.2015
Сообщения
98
Благодарностей
3
Баллы
8
ты крутой чувак, спасибо за статью, очень интересно
 

temass

Client
Регистрация
06.06.2015
Сообщения
98
Благодарностей
3
Баллы
8
Скажи пожалуйста а если мы ищем пул элементов Tab1.FindElementsByXPath ("//div[@class='prodGallery']/div/ul/li/img"), как нам эти элементы вывести в столбик, а не в строчку, начиная с определенного столбца таблицы?

C#:
Tab1.FindElementsByXPath ("//div[@class='prodGallery']/div/ul/li/img")
                    .Select(h=>
                    h.GetAttribute("src") +","+)
                    .ToList()
                    .ForEach(s=>TableUsage.AddRow(s));
 

Кто просматривает тему: (Всего: 1, Пользователи: 0, Гости: 1)