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

  • Автор темы Автор темы evgen2208
  • Дата начала Дата начала

evgen2208

Client
Регистрация
12.10.2016
Сообщения
130
Реакции
163
Баллы
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 отличается).

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

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

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

Вложения

Последнее редактирование модератором:
А я было начал печалиться из-за отсутствия статей для 11-го Конкурса, написанных на высоком техническом уровне. Мое уважение автору за новые идеи и фишки, а также за профессионализм.
 
Крутая статья!! но много мест не понятных, надо глубже мне еще изучать с#
 
  • Спасибо
Реакции: evgen2208
Ещё особо не вникал, но на первый взгляд пока это лучшее за сезон.
 
  • Спасибо
Реакции: evgen2208 и molotok
Заметил одну особенность, как только начинаю углублять свои знания по теме, или переписывать свои проекты (улучшая код), то в конкурсе появляются хорошие статьи по теме.
 
Заметил одну особенность, как только начинаю углублять свои знания по теме, или переписывать свои проекты (улучшая код), то в конкурсе появляются хорошие статьи по теме.
это называется Феномен Баадера-Майнхоф :D
 
это называется Феномен Баадера-Майнхоф :D
Не важно как называется, главное чтобы полезное было. А то помню в детстве, я только книжку какую нибудь прочитаю, так через неделю-две, по ТВ фильм показывают по мотивам этой книжки. :D
 
круто! спасибо, в закладки однозначно !
 
У меня не работает шаб, может каких то библиотек не хватает? Подскажи плиз, а то уже час жёстко *усь))
 
У меня не работает шаб, может каких то библиотек не хватает? Подскажи плиз, а то уже час жёстко *усь))
что за ошибка?
Библиотек нет никаких. Версия ЗП где-то полугодичной давности (не помню какая была), еще до хрома.
 
Сам не понимаю
 

Вложения

  • Screenshot_1.jpg
    Screenshot_1.jpg
    214,3 KB · Просмотры: 780
Вот
 

Вложения

  • Log.jpg
    Log.jpg
    143,6 KB · Просмотры: 824
нажми на это сообщение лога, откроется кубик с ошибкой.
там код закоментированный:
Код:
Развернуть Свернуть Копировать
//урл для переход на страницу надо предварительно
//получить из таблицы в отдельном кубике
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
Единственная содержательная статья в 11-ом конкурсе.
 
  • Спасибо
Реакции: evgen2208
Крутая и полезная статья, автору респект и мой голос!)
 
  • Спасибо
Реакции: evgen2208
Хорошо пояснил, особенно для новичков в с#
 
Доброго времени. Ошибки:
991dece3-b929-4e1d-9449-898b737eb457
99ad46df-cf4e-41c7-86da-4ade1cf6438d
99ad46df-cf4e-41c7-86da-4ade1cf6438d
8579b1d3-409e-4e7b-a3cc-d2c216766960
 
Доброго времени. Ошибки:
991dece3-b929-4e1d-9449-898b737eb457
99ad46df-cf4e-41c7-86da-4ade1cf6438d
99ad46df-cf4e-41c7-86da-4ade1cf6438d
8579b1d3-409e-4e7b-a3cc-d2c216766960
кинь лучше скрин с логами(включать Окна->Лог), нормальное описание ошибки будет.
 
Очень круто! Я как раз не понимал лямбда выражения и все планировал с этим разобраться. Огромное спасибо!
 
И кстати, такой универсальный кубик для регистрации я тоже разрабатывал, только для о работы на запросах и сайты с рекапечей реально самые уязвимые:-)
 
Код:
Развернуть Свернуть Копировать
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
 
Последнее редактирование:
Код:
Развернуть Свернуть Копировать
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
ты крутой чувак, спасибо за статью, очень интересно
 
Скажи пожалуйста а если мы ищем пул элементов 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));
 

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