Сниппеты эмуляции мыши: FullEmulationMouse

Discussion in 'Снипеты' started by LaGir, Feb 28, 2017.

  1. LaGir

    LaGir Client

    Joined:
    Oct 1, 2015
    Messages:
    181
    Likes Received:
    506
    Приветствую всех!

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

    Итак, появилось несколько методов работы с виртуальной мышью, доступных из C#-кода.
    Самый интересный, несомненно, FullEmulationMouseMoveAboveHtmlElement, предназначенный для эмуляции чтения. Метод принимает в качестве параметров элемент страницы, который нужно "прочесть", и некий sizeOfType в виде некоего числа. На момент создания темы до сих пор непонятно, что это за sizeOfType такой - в документации объяснения нет, от разработчиков конкретного ответа тоже не было. Много тестил поведение метода с различными значениями, но так и не пришёл к понятному объяснению, как и на что влияет этот параметр. Если кто-то понял его назначение, или хотя бы есть однозначные предположения - большая просьба отписаться.
    Также добавлю, что в ходе тестов не получилось найти и оптимального значения sizeOfType, при котором эмуляция чтения смотрелась бы более-менее реалистично. Моё мнение - над реализацией этой виртуальной мыши разработчикам ещё работать и работать.

    Но довольно о проблемах. Так как виртуальная мышь сейчас доступна только из кода, с которым немало пользователей ZennoPoster "на Вы", разберём пару простых задач с применением виртуальной мыши. Для примера возьмём главную страницу известного портала 4pda.

    Задача 1: "прочитать" рандомный пост с главной страницы и перейти к его полной версии.
    Code (CSharp):
    1. var rnd = new Random();
    2.  
    3. //Переходим на целевую страничку
    4. Tab tab1 = instance.ActiveTab;
    5. tab1.Navigate("http://4pda.ru/");
    6. if (tab1.IsBusy)    tab1.WaitDownloading();
    7.  
    8. //Находим коллекцию элементов-постов (на главной нашего сайта их 30 штук)
    9. //Эти элементы будем использовать как родительские, для поиска заголовка и контента каждого из постов
    10. var posts = tab1.FindElementsByXPath("//article[@class='post']");
    11. //Я обычно использую XPath, но можно искать и просто по атрибутам:
    12. //posts = tab1.FindElementsByAttribute("article", "class", "post", "text");
    13.  
    14. //Если ни одного поста не найдено, выходим из сниппета по красной ветке
    15. if (posts.Count==0)    throw new Exception("Посты не найдены!");
    16.  
    17. //Получаем рандомный пост на странице
    18. var post = posts.GetByNumber(rnd.Next(0,posts.Count));
    19.  
    20. //Ведём мышку к этому посту
    21. tab1.FullEmulationMouseMoveToHtmlElement(post);
    22.  
    23. //Ищем заголовок поста
    24. var h2 = post.FindChildByXPath(".//h2",0);
    25. //Проводим мышкой по заголовку
    26. tab1.FullEmulationMouseMoveAboveHtmlElement(h2, 30);
    27.  
    28. //Ищем текст поста
    29. var p = post.FindChildByXPath(".//p",0);
    30. //Проводим мышкой по тексту
    31. tab1.FullEmulationMouseMoveAboveHtmlElement(p, 40);
    32.  
    33. Thread.Sleep(2000);    //Пауза 2 с
    34.  
    35. //Ведём мышку к кнопке "далее" и кликаем по ней
    36. var more = post.FindChildByXPath(".//a[text()='далее']",0);
    37. tab1.FullEmulationMouseMoveToHtmlElement(more);
    38. tab1.FullEmulationMouseClick("left", "click");

    Задача 2: "прочитать" все посты на главной странице.
    Code (CSharp):
    1. var rnd = new Random();
    2.  
    3. //Переходим на целевую страничку
    4. Tab tab1 = instance.ActiveTab;
    5. tab1.Navigate("http://4pda.ru/");
    6. if (tab1.IsBusy)    tab1.WaitDownloading();
    7.  
    8. //Находим коллекцию элементов-постов
    9. var posts = tab1.FindElementsByXPath("//article[@class='post']");
    10.  
    11. //Проходим в цикле по каждому посту
    12. foreach (var post in posts.Elements){
    13.  
    14.     //Ищем заголовок поста
    15.     var h2 = post.FindChildByXPath(".//h2",0);
    16.     //Проводим мышкой по заголовку, для второго параметра используем рандом (например, от 30 до 50)
    17.     tab1.FullEmulationMouseMoveAboveHtmlElement(h2, rnd.Next(30,50));
    18.     //Делаем случайную паузу от 0,1 до 1 секунды
    19.     Thread.Sleep(rnd.Next(1,10) * 100);
    20.  
    21.     //Ищем текст поста
    22.     var p = post.FindChildByXPath(".//p",0);
    23.     //Проводим мышкой по тексту
    24.     tab1.FullEmulationMouseMoveAboveHtmlElement(p, rnd.Next(30,50));
    25.     //Делаем случайную паузу от 0,5 до 3 секунд
    26.     Thread.Sleep(rnd.Next(4,30) * 100);
    27.  
    28.     //Для доп рандомизации (или просто опытов), можно также после "прочтения" каждого поста менять настройки движения мышки (метод доступен с версии 5.10.4.1)
    29.     //По умолчанию каждый параметр равен 5. Для их изменения также можно применять рандом:
    30.     //t1.FullEmulationMouseSetOptions(rnd.Next(3,20), 5, rnd.Next(5,10));
    31. }
    Перед использованием методов FullEmulationMouseMoveAboveHtmlElement и FullEmulationMouseSetOptions рекомендую потестить разные значения их целочисленных параметров, возможно вам удастся получить более адекватные движения мышки.

    Если у вас вопросы, идеи сниппетов, или же есть самим что написать по теме виртуальной мыши - жду ваших сообщений в топике. :-)
     
  2. LaGir

    LaGir Client

    Joined:
    Oct 1, 2015
    Messages:
    181
    Likes Received:
    506
    Рассмотрим подробнее метод FullEmulationMouseSetOptions, доступный с версии 5.10.4.1.
    Предназначен он для установки параметров эмуляции мыши, причём после каждого вызова метода Navigate параметры сбрасываются на значения по умолчанию.

    Параметры.
    1. pause

    Описание. Пауза в миллисекундах при генерации следующей точки для движения мыши.
    Значение по умолчанию: 5.
    Стоит ли менять? В принципе, на мой взгляд значение по умолчанию вполне себе оптимальное. Если его уменьшить - мышка будет двигаться быстрее, и наоборот. Причём увеличить скорость передвижения мышки таким способом получится сравнительно немного (опускаем значение с 5 до 0), а вот замедлить можно очень сильно (поднимаем значение с 5 до скольки угодно).

    2. pauseVariance
    Описание. Отклонение для паузы (1-й параметр). Пример работы: если пауза стоит 50 мс, а отклонение 10 мс - пауза будет случайной в диапазоне от 40 до 60 мс.
    Значение по умолчанию: 5.
    Стоит ли менять? Тоже вполне можно считать оптимальным значением. Но, конечно, поиграться с паузами лично - хорошая идея, возможно найдёте для себя значения получше.

    3. pointDistanse
    Описание. Длина шага по прямой линии между генерируемыми точками.
    Значение по умолчанию: 5.
    Стоит ли менять? Вот этот параметр, на мой взгляд, стоит активно использовать для изменения скорости движения мыши. Изменять это значение нужно осторожно, ибо увеличение даже до 20 сильно ускоряет движение мыши.

    Выводы.
    По умолчанию скорость мыши в методах FullEmulationMouse неизменна, в результате чего эмуляция легко палится, мягко говоря. Скорость движения мышки реального человека как правило постоянно меняется, нередко встречаются быстрые рывки.
    Следовательно, для лучшей эмуляции, после каждого применения методов движения FullEmulationMouse в идеале чутка менять параметры метода FullEmulationMouseSetOptions, как минимум для изменения скорости движения мыши.
    Конечно, вряд ли можно сказать, что эти действия существенно "очеловечат" движения, но по крайней мере некоторые действия (а именно - движение мыши на большое расстояние и "чтение" большого количества текста) будут выглядеть на порядок правдоподобнее.

    Разберём регулярное изменение скорости мыши с помощью этого метода, на примере первого сниппета из прошлого поста.
    Code (CSharp):
    1. var rnd = new Random();
    2. //Переходим на целевую страничку
    3. Tab tab1 = instance.ActiveTab;
    4. tab1.Navigate("http://4pda.ru/");
    5. if (tab1.IsBusy)    tab1.WaitDownloading();
    6. //Находим коллекцию элементов-постов
    7. var posts = tab1.FindElementsByXPath("//article[@class='post']");
    8. //Если ни одного поста не найдено, выходим из сниппета по красной ветке
    9. if (posts.Count==0)    throw new Exception("Посты не найдены!");
    10.  
    11. //Находим 1-й пост на странице
    12. var post = posts.GetByNumber(1);
    13.  
    14. //Меняем скорость и ведём мышкой к посту
    15. tab1.FullEmulationMouseSetOptions(5,5,14);
    16. tab1.FullEmulationMouseMoveToHtmlElement(post);
    17. Thread.Sleep(1000);    //Пауза 1 с
    18.  
    19. //Снова меняем скорость (чуть медленнее) и проводим мышкой по заголовку
    20. tab1.FullEmulationMouseSetOptions(5,5,8);
    21. var h2 = post.FindChildByXPath(".//h2",0);    //Поиск заголовка поста
    22. tab1.FullEmulationMouseMoveAboveHtmlElement(h2, 30);
    23. Thread.Sleep(1000);    //Пауза 1 с
    24.  
    25. //Снова меняем скорость (ещё медленнее, а-ля более внимательное чтение) и проводим мышкой по тексту поста
    26. tab1.FullEmulationMouseSetOptions(5,5,3);
    27. var p = post.FindChildByXPath(".//p",0);    //Поиск текста поста
    28. tab1.FullEmulationMouseMoveAboveHtmlElement(p, 40);
    29.  
    30. //Также напоминаю, что настройки мыши можно задавать рандомно
    31. //Например, так случайным образом будет задаваться 3-й параметр в диапазане от 4 до 10:
    32. tab1.FullEmulationMouseSetOptions(5,5,rnd.Next(4,11));
    Запустив сниппет, можно наглядно увидеть, что скорость движения мыши в этих 3-х действиях ощутимо различалась, и была уже более похожа на человеческие (нежели в первых сниппетах, по крайней мере). 1 движение - резкое движени курсора к посту, 2 движение - быстрое чтение заголовка, 3 движение - медленное чтение текста поста.

    Ещё важный момент. Если запустить этот сниппет, но указать не 1 пост, а например 10, то можно заметить ещё одну проблему текущей реализации виртуальной мыши: при передвижении мышки далеко вниз или далеко вверх по странице (скролл по сути) - настройки мыши нифига не работают, мышка тащится медленно и с одинаковой скоростью, что очень не по-человечески. Возможно, именно этот момент разберём в следующей "серии" более подробно. :-)
     
  3. LaGir

    LaGir Client

    Joined:
    Oct 1, 2015
    Messages:
    181
    Likes Received:
    506
    За работой немного позабыл об этой темке хотя давно пора было ответить на вопрос, который задавал в первом посте темы. VladZen в этом сообщении объяснил, что sizeOfType, второй параметр метода FullEmulationMouseMoveAboveHtmlElement относится к отступам/примерному размеру шрифта "читаемого" текста. Спасибо пользователю @Серёжа за напоминание в личку об этом параметре.

    Также, упоминал о проблеме прокрутки в предыдущем посте - с этим реальные проблемы, тестил разные варианты, любой способ скролла не может корректно работать вместе с методами FullEmulationMouse. Также, об этом уже написали в этой теме, но походу разработчики считали имеющийся скролл правдоподобным и что его достаточно. Однако, надежда есть.


    Ну и, раз уж пишу пост, можно ещё и по теме примеров что-нибудь написать.
    Рано или поздно новой виртуальной мышью можно будет рулить из кубиков, и примеры в этой темке потеряют часть своей актуальности. Однако, многие вещи по теме именно увеличения качества эмуляции проще и легче делать в коде.
    Поэтому, предлагаю сегодня рассмотреть рандомное "чтение" каких-либо текстов виртуальной мышью, на примере заголовков из примеров первого поста темки.

    Суть - если заголовок достаточно короткий, то пользователь вполне может его пропустить курсором, быстро прочитав только глазами.
    Можно это эмулировать, вытащив текст заголовка, псчитав количество его символов, и - если их меньше, скажем, 30 - пропускать. Берём за основу этот кусок кода из сниппета первого поста:
    Code (CSharp):
    1. //Ищем заголовок поста
    2. var h2 = post.FindChildByXPath(".//h2",0);
    3. //Проводим мышкой по заголовку, для второго параметра используем рандом (например, от 30 до 50)
    4. tab1.FullEmulationMouseMoveAboveHtmlElement(h2, rnd.Next(30,50));
    Переделываем согласно вышеизложенному:
    Code (CSharp):
    1. var h2 = post.FindChildByXPath(".//h2",0);
    2. int h2min = 30;        //Задаём минимальную длину заголовка для прочтения
    3. int h2dlina = post.InnerText.Length;    //Определяем длину заголовка в символах
    4. if (h2dlina > h2min){        //Если длина заголовка больше мин. значения - читаем заголовок
    5.     tab1.FullEmulationMouseMoveAboveHtmlElement(h2, rnd.Next(30,50));
    6. }
    Итог: мышка проведёт по заголовку, если он длиннее или равен 30 символам, иначе - просто пропустит.

    Можно ещё модернизировать. Скажем, если длина заголовка меньше 30 символов, то одно из двух: с вероятностью 33% "читаем" заголовок, с вероятностью 67% - пропускаем. Вероятность задаём в третьей строчке.

    Code (CSharp):
    1. var h2 = post.FindChildByXPath(".//h2",0);
    2. int h2min = 30;        //Задаём минимальную длину заголовка для прочтения
    3. int ver = 33;        //Задаём вероятность прочтения заголовка меньше 'h2min' символов, в процентах
    4. int h2dlina = post.InnerText.Length;    //Определяем длину заголовка в символах
    5. int prsnt = rnd.Next(100);
    6. if ((h2dlina < h2min && prsnt >= ver) || h2dlina >= h2min){
    7.     //Заголовки
    8.     tab1.FullEmulationMouseMoveAboveHtmlElement(h2, 30);
    9. }
    Полный вариант сниппета из первого поста с обновлённым "чтением" заголовков под спойлером.
    Code (CSharp):
    1. var rnd = new Random();
    2.  
    3. //Переходим на целевую страничку
    4. Tab tab1 = instance.ActiveTab;
    5. tab1.Navigate("http://4pda.ru/");
    6. if (tab1.IsBusy)    tab1.WaitDownloading();
    7.  
    8. //Находим коллекцию элементов-постов
    9. var posts = tab1.FindElementsByXPath("//article[@class='post']");
    10.  
    11. //Проходим в цикле по каждому посту
    12. foreach (var post in posts.Elements){
    13.  
    14.     //Ищем заголовок поста
    15.     var h2 = post.FindChildByXPath(".//h2",0);
    16.     int h2min = 30;        //Задаём минимальную длину заголовка для прочтения
    17.     int ver = 33;        //Задаём вероятность прочтения заголовка меньше 'h2min' символов, в процентах
    18.     int h2dlina = post.InnerText.Length;    //Определяем длину заголовка в символах
    19.     int prsnt = rnd.Next(100);
    20.     if ((h2dlina < h2min && prsnt >= ver) || h2dlina >= h2min){
    21.         //Заголовки
    22.         tab1.FullEmulationMouseMoveAboveHtmlElement(h2, 30);
    23.     }
    24.     //Делаем случайную паузу от 0,1 до 1 секунды
    25.     Thread.Sleep(rnd.Next(1,10) * 100);
    26.  
    27.     //Ищем текст поста
    28.     var p = post.FindChildByXPath(".//p",0);
    29.     //Проводим мышкой по тексту
    30.     tab1.FullEmulationMouseMoveAboveHtmlElement(p, rnd.Next(30,50));
    31.     //Делаем случайную паузу от 0,5 до 3 секунд
    32.     Thread.Sleep(rnd.Next(4,30) * 100);
    33.  
    34.     //Для доп рандомизации (или просто опытов), можно также после "прочтения" каждого поста менять настройки движения мышки (метод доступен с версии 5.10.4.1)
    35.     //По умолчанию каждый параметр равен 5. Для их изменения также можно применять рандом:
    36.     //t1.FullEmulationMouseSetOptions(rnd.Next(3,20), 5, rnd.Next(5,10));
    37. }

    Не знаю, какую конструкцию придётся соорудить из кубиков для реализации этого простого "баффа" эмуляции, но полагаю что немаленькую - так что думаю кому-то эти несколько строк будут полезными. :-)
     
  4. sergiksergik

    sergiksergik Client

    Joined:
    Dec 6, 2011
    Messages:
    595
    Likes Received:
    110
    Заметил что одинаковые элементы, только с разным left, кликает по одним и тем же координатам каждого элемента
    К примеру горизонтальное меню
     
  5. Juniorcpa

    Juniorcpa Client

    Joined:
    May 27, 2014
    Messages:
    1,159
    Likes Received:
    511
    Спасибо за статьи. Очень круто и подробно расписано.
     
    leha52rus and LaGir like this.
  6. zenfreak

    zenfreak Client

    Joined:
    Aug 21, 2013
    Messages:
    242
    Likes Received:
    9
    Если значение по умолчанию для паузы составляет 5 миллисекунд, а дисперсия паузы также составляет 5 миллисекунд, значит ли это, что пауза будет случайным значением от 0 до 10 миллисекунд?
     
  7. LaGir

    LaGir Client

    Joined:
    Oct 1, 2015
    Messages:
    181
    Likes Received:
    506
    Верно.
     
    zenfreak likes this.
  8. socrobotic

    socrobotic Client

    Joined:
    Feb 14, 2016
    Messages:
    163
    Likes Received:
    41
    блин надо было сразу же до конца дочитать и взять эти строчки))) а так пришлось сначала 1 код поставить по себя сделать, потом дальше и в итоге просто всю ветку перечитала и добавила последний варинат, реально крутое решеие, пасибо!
     
    leha52rus and LaGir like this.
  9. chutev

    chutev Client

    Joined:
    Jan 23, 2016
    Messages:
    111
    Likes Received:
    15
    Делаю для одного сайта эмуляцию движения мыши, появилась проблема. В определенный момент, когда курсор движется к найденному элементу, он как будто залипает и не переставая двигаться в этом направлении упирается в край экрана. Прервать, в этом случает, можно только закрыв окно. Элемент на странице присутствует. Может у кого была такая проблема, как лечить? Или может есть какой то способ, что бы прервать выполнение кубика с#?
     
  10. esouldy

    esouldy Client

    Joined:
    Feb 28, 2016
    Messages:
    184
    Likes Received:
    85
    возможно элемент не один, и курсор хватается за другой, с координатой меньше или равной нулю, либо же скрытый. собирай элементы в массив и проверяй координаты
     
    chutev likes this.
  11. Redsmokky

    Redsmokky Client

    Joined:
    Oct 6, 2015
    Messages:
    211
    Likes Received:
    87
    Делаешь в ПМ норм отрабатывает, а ЗП бывает что вылетает за край экрана почему-то элемент и виснет инстанс, со скролом та же фигня, поток потом жрет ЦП и память пока не сдохнет и ЗП его не закроет. Хз как убрать эту штуку
     
  12. LaGir

    LaGir Client

    Joined:
    Oct 1, 2015
    Messages:
    181
    Likes Received:
    506
    С момента моих последних постов в этой теме появилось ещё несколько методов виртуальной мыши: FullEmulationMouseWheel (5.10.7.0), FullEmulationMouseDragAndDrop и FullEmulationMouseSetScrollBorder (5.11.6.0).
    Давайте кратко рассмотрим эти методы.

    1. FullEmulationMouseWheel
    Данный метод предназначен для эмуляции прокрутки колёсиком мыши.
    Метод принимает 2 параметра типа int:
    • deltaX - величина в пикселях, на которую прокрутится страница по горизонтали (ось x)
    • deltaY - величина в пикселях, на которую прокрутится страница по вертикали (ось y)

    Если нужно крутить вниз, то указываем положительное значени, если вверх - отрицательное.
    Code (CSharp):
    1. //Делаем прокрутку на 500 пикселей ВНИЗ (по y)
    2. instance.ActiveTab.FullEmulationMouseWheel(0, 500);
    3. //Делаем прокрутку на 500 пикселей ВВЕРХ (по y)
    4. instance.ActiveTab.FullEmulationMouseWheel(0, -500);
    Пример использования. Допустим, есть кнопка далеко внизу страницы, нужно проскролить и кликнуть по ней.
    Code (CSharp):
    1. //Находим элемент кнопки
    2. var elButton = instance.ActiveTab.FindElementByXPath("//button", 0);
    3. //Определяем, на каком расстоянии от верха страницы находится кнопка
    4. int topInBrowser = int.Parse(elButton.GetAttribute("topInBrowser"));
    5. //Делаем прокрутку на это расстояние
    6. instance.ActiveTab.FullEmulationMouseWheel(0, topInBrowser);
    7. //Ведём курсор мышки к кнопке
    8. instance.ActiveTab.FullEmulationMouseMoveToHtmlElement(elButton);
    9. //Кликаем
    10. instance.ActiveTab.FullEmulationMouseClick("left", "click");

    2. FullEmulationMouseDragAndDrop
    Данный метод предназначен для эмуляции перетаскивания элементов мышкой по принципу DragAndDrop.
    У него есть 2 перегрузки - перетаскивание по координатам, перетаскивание одного элемента на другой.

    Перетаскивание по координатам:
    Code (CSharp):
    1. //Координата по X, от которой начинаем перетаскивание
    2. int fromX = 400;
    3. //Координата по Y, от которой начинаем перетаскивание
    4. int fromY = 100;
    5. //Координата по X, на которую тащим
    6. int toX = 500;
    7. //Координата по Y, на которую тащим
    8. int toY = 300;
    9.  
    10. //Перетаскиваем по координатам
    11. instance.ActiveTab.FullEmulationMouseDragAndDrop(fromX, fromY, toX, toY);
    Перетаскивание элементов:
    Code (CSharp):
    1. //Находим 1-й элемент
    2. var el1 = instance.ActiveTab.FindElementByXPath("//img[@class='logo']", 0);
    3. //Находим 2-й элемент
    4. var el2 = instance.ActiveTab.FindElementByXPath("//textarea[@id='field']", 0);
    5. //Перетаскивание 1-го элемента на 2-ой
    6. instance.ActiveTab.FullEmulationMouseDragAndDrop(el1, el2);

    3. FullEmulationMouseSetScrollBorder
    Данный метод предназначен для установки положения курсора мыши относительно края страницы во время прокрутки. Например, по умолчанию при прокрутке страницы курсор останавливается в 20 пикселях от края страницы, в сторону которого производится прокрутка.
    Метод принимает 2 параметра типа int:
    • scrollX - расстояния курсора мыши от края страницы при горизонтальном скролле
    • scrollY - расстояния курсора мыши от края страницы при вертикальном скролле
    ScrollY.jpg

    Code (CSharp):
    1. //Меняем значения границ скролла на 0 для горизонтальной прокрутки и 10 для вертикальной
    2. instance.ActiveTab.FullEmulationMouseSetScrollBorder(0, 10);
     
  13. Juniorcpa

    Juniorcpa Client

    Joined:
    May 27, 2014
    Messages:
    1,159
    Likes Received:
    511
    А давай рассмотрим эти методы на основе актуального сайта?)
     
    LaGir likes this.
  14. LaGir

    LaGir Client

    Joined:
    Oct 1, 2015
    Messages:
    181
    Likes Received:
    506
    Можно, давай актуальный сайт и какие действия на нём делать :-)
     
    lzlmrf and Dimionix like this.
  15. Juniorcpa

    Juniorcpa Client

    Joined:
    May 27, 2014
    Messages:
    1,159
    Likes Received:
    511
    Zennolab.com, авторизация, поиск этой темы, написать сюда что-нибудь :-)
     
  16. chutev

    chutev Client

    Joined:
    Jan 23, 2016
    Messages:
    111
    Likes Received:
    15
    Элемент на странице есть. Мышка тупо пробегает мимо.
     
  17. LaGir

    LaGir Client

    Joined:
    Oct 1, 2015
    Messages:
    181
    Likes Received:
    506
    Конкретно для демонстрации методов мыши необычный вариант, но почему бы и нет. :-) Добавил ещё поиск последнего поста в теме и его "чтение".
    Только сорре, что к мыши не относится - тоже в коде, на кубиках разучился писать (зато почти всё закомменчено).

    Прикрепляю шаблон к сообщению. Для ленивых - содержимое сниппетов под спойлерами.
    Code (CSharp):
    1. //Получаем логин и пароль из переменных проекта
    2. string login = project.Variables["login"].Value;
    3. string pass = project.Variables["pass"].Value;
    4.  
    5. //Заходим на ZennoLab
    6. var tab = instance.ActiveTab;
    7. tab.Navigate("http://zennolab.com/discussion/");
    8. if (tab.IsBusy)    tab.WaitDownloading();
    9. Helper.Pause();
    10.  
    11.  
    12. //Логинимся
    13.  
    14. //Поиск кнопки по XPath
    15. var elLogIn = tab.FindElementByXPath("//a[contains(@href,'login')]", 0);
    16. //Поиск кнопки по атрибутам
    17. //var elLogIn = tab.FindElementByAttribute("a", "href", "login/", "text", 0);
    18.  
    19. //Ведём мышку к кнопке
    20. tab.FullEmulationMouseMoveToHtmlElement(elLogIn);
    21. //Задержка совсем чуть-чуть (от 200 до 400 мс)
    22. Helper.Pause(2,5);
    23. //Клакием по кнопке
    24. tab.FullEmulationMouseClick("left", "click");
    25.  
    26. //Задержка на выезд панельки (от 1 до 2 с)
    27. Helper.Pause(10,21);
    28.  
    29. //Ищем поля логина и пароля, кнопку входа
    30. var elMail = tab.FindElementByXPath("//input[@name='login']", 0);
    31. var elPass = tab.FindElementByXPath("//input[@name='password']", 0);
    32. var elLogInBtn = tab.FindElementByXPath("//input[@class='button primary']", 0);
    33.  
    34. //Проверяем, выдвинулась ли панелька с формой входа
    35. if (int.Parse(elMail.GetAttribute("topInTab"))<0)
    36.     throw new Exception("Фигня какая-то, брат, форма с авторизацией не выдвигается!");
    37.  
    38. //Изменяем настройки мыши (теперь двигается чутка быстрее)
    39. tab.FullEmulationMouseSetOptions(5,5,10);
    40. //Ведём её к полю ввода email/логина
    41. tab.FullEmulationMouseMoveToHtmlElement(elMail);
    42. //Кликаем по полю
    43. tab.FullEmulationMouseClick("left", "click");
    44. //Вводим логин
    45. elMail.SetValue(login, "Middle");
    46. //Микропауза (300-700 мс)
    47. Helper.Pause(3,8);
    48.  
    49. //Возвращаем настройки мыши к стандартным
    50. tab.FullEmulationMouseSetOptions();
    51. //Ведём её к полю ввода пароля
    52. tab.FullEmulationMouseMoveToHtmlElement(elPass);
    53. //Кликаем по полю
    54. tab.FullEmulationMouseClick("left", "click");
    55. //Вводим пароль
    56. elPass.SetValue(pass, "Middle");
    57. //Микропауза (300-700 мс)
    58. Helper.Pause(3,8);
    59.  
    60. //Ведём мышь к кнопке входа
    61. tab.FullEmulationMouseMoveToHtmlElement(elLogInBtn);
    62. //Микропауза (200-500 мс)
    63. Helper.Pause(2,6);
    64. //Кликаем по кнопке
    65. tab.FullEmulationMouseClick("left", "click");
    66. //Ждём прогрузку
    67. if (tab.IsBusy)    tab.WaitDownloading();
    68. Helper.Pause();
    Code (CSharp):
    1. //Название темки
    2. string searchText = project.Variables["searchText"].Value;
    3.  
    4. var tab = instance.ActiveTab;
    5.  
    6. //Ищем поле поиска по форуму
    7. var elSearchField = tab.FindElementByXPath("//input[@id='QuickSearchQuery']", 0);
    8. //Подведём к нему мышь. Для разнообразия, по координатам
    9. //Находим координату середины поля по x
    10. int toX = int.Parse(elSearchField.GetAttribute("leftInBrowser")) + elSearchField.Width/2;
    11. //Находим координату середины поля по y
    12. int toY = int.Parse(elSearchField.GetAttribute("topInBrowser")) + elSearchField.Height/2;
    13. //Ведём мышь к найденным координатам
    14. tab.FullEmulationMouseMove(toX, toY);
    15. //Микропауза (200-500 мс)
    16. Helper.Pause(2,6);
    17. //Клик
    18. tab.FullEmulationMouseClick("left", "click");
    19. //Микропауза (200-500 мс)
    20. Helper.Pause(2,6);
    21. //Вводим строку поиска
    22. elSearchField.SetValue(searchText, "Middle");
    23.  
    24. //Ищем кнопку поиска
    25. var elSearchButton = tab.FindElementByXPath("//input[contains(@class,'button primar')]", 0);
    26. //Ведём к ней мышь
    27. tab.FullEmulationMouseMoveToHtmlElement(elSearchButton);
    28. //Микропауза (200-500 мс)
    29. Helper.Pause(2,6);
    30. //Кликаем по кнопке
    31. tab.FullEmulationMouseClick("left", "click");
    32.  
    33. //Ждём прогрузку страницы
    34. if (tab.IsBusy)    tab.WaitDownloading();
    35. Helper.Pause();
    36.  
    37. //Ищем ссылку на тему
    38. var elTopicLink = tab.FindElementByXPath("//a[string()='" + searchText + "']", 1);
    39. //Ведём к ней мышку
    40. tab.FullEmulationMouseMoveToHtmlElement(elTopicLink);
    41. //Микропауза (200-500 мс)
    42. Helper.Pause(2,6);
    43. //Кликаем по ссылке
    44. tab.FullEmulationMouseClick("left", "click");
    45.  
    46. //Ждём прогрузку страницы
    47. if (tab.IsBusy)    tab.WaitDownloading();
    48. Helper.Pause();
    Code (CSharp):
    1. //Текст поста
    2. string text = project.Variables["postText"].Value;
    3.  
    4. var tab = instance.ActiveTab;
    5.  
    6. //Находим на странице последний пост
    7. var elLastPost = tab.FindElementByXPath("//li[contains(@id,'post-')][last()]", 0);
    8. //Ищем, где на странице расположен пост
    9. //Находим координату начала поста по y
    10. int toY = int.Parse(elLastPost.GetAttribute("topInBrowser"));
    11. //Если от текущего положения мыши на странице до последнего поста далеко (свыше 2000 пикселей)
    12. if ((toY-tab.FullEmulationMouseCurrentPosition.Y) > 2000){
    13.     //То крутим колесико мышки на это расстояние
    14.     tab.FullEmulationMouseWheel(0, toY-tab.FullEmulationMouseCurrentPosition.Y);
    15. }
    16.  
    17. //Микропауза (400-900 мс)
    18. Helper.Pause(4,10);
    19.  
    20. //Находим текст поста
    21. var elLastPostText = elLastPost.FindChildByXPath(".//article",0);
    22. //"Читаем" его мышкой
    23. tab.FullEmulationMouseMoveAboveHtmlElement(elLastPostText, 35);
    24.  
    25. //Находим поле для ответа
    26. var replyField = tab.FindElementByXPath("//body[@dir='LTR']", 0);
    27. //Ведём к полю мышку
    28. tab.FullEmulationMouseMoveToHtmlElement(replyField);
    29. //Микропауза (200-500 мс)
    30. Helper.Pause(2,6);
    31. //Кликаем по полю
    32. tab.FullEmulationMouseClick("left", "click");
    33. //Вводим текст ответа
    34. replyField.SetValue(text, "Middle");
    35. //Микропауза (800-1100 мс)
    36. Helper.Pause(8,12);
    37.  
    38. //Находим кнопку отправки ответа
    39. var replySubmit = tab.FindElementByXPath("//div[@class='draftUpdate']/following-sibling::input[contains(@class,'button primar')]", 0);
    40. //Ведём к ней мышку
    41. tab.FullEmulationMouseMoveToHtmlElement(replySubmit);
    42. //Микропауза (800-1100 мс)
    43. Helper.Pause(8,12);
    44. //Кликаем по кнопке
    45. //tab.FullEmulationMouseClick("left", "click");
    46.  
    47. //Ждём прогрузку страницы
    48. if (tab.IsBusy)    tab.WaitDownloading();
    49. Helper.Pause();
     

    Attached Files:

    redman, leha52rus, Nord and 14 others like this.
  18. Juniorcpa

    Juniorcpa Client

    Joined:
    May 27, 2014
    Messages:
    1,159
    Likes Received:
    511
    Спасибо за то, что делаешь :-)
     
    Last edited: Dec 11, 2017
    LaGir likes this.
  19. Gizmond

    Gizmond Client

    Joined:
    Feb 18, 2017
    Messages:
    133
    Likes Received:
    16
    Добрый день! Подскажите пожалуйста. Как вставить значение из переменной в этот кусок кода.

    Code (text):
    1. var posts = tab1.FindElementsByAttribute("a", "href", "Сюда значение из меременной", "regexp");
    пробывал так :

    var TestVar = project.Variables["b"].Value;

    и потом TestVar подставлять туда - не катит. Я просто не особо разбираюсь в сшарп, поэтому пробовал разные варианты )
     
  20. Gizmond

    Gizmond Client

    Joined:
    Feb 18, 2017
    Messages:
    133
    Likes Received:
    16
    Разобрался) Все правильно делал. Завернул переменку в TestVar и нужно было вставить ее в код без " "

    получилось вот так

    var TestVar = project.Variables["b"].Value;
    var posts = tab1.FindElementsByAttribute("a", "href", TestVar, "regexp");
     
    LaGir likes this.
  21. ezotonal

    ezotonal Client

    Joined:
    Jan 13, 2014
    Messages:
    504
    Likes Received:
    101
    Можно просто переменную вставить

    Code (text):
    1. var posts = tab1.FindElementsByAttribute("a", "href", project.Variables["b"].Value, "regexp");
     
  22. Gizmond

    Gizmond Client

    Joined:
    Feb 18, 2017
    Messages:
    133
    Likes Received:
    16
    Да я так и сделал ) Потом уже доперло
     
  23. Juniorcpa

    Juniorcpa Client

    Joined:
    May 27, 2014
    Messages:
    1,159
    Likes Received:
    511
    Компиляция кода Ошибка в действии "CS0103" "Имя "Helper" отсутствует в текущем контексте". [Строка: 4; Cтолбец: 1]
    - такие дела :-)
     
  24. LaGir

    LaGir Client

    Joined:
    Oct 1, 2015
    Messages:
    181
    Likes Received:
    506
    Либо скопируй из того шаблона к себе блок директив и общего кода, либо замени в сниппетах все строчки вида:
    Code (CSharp):
    1. Helper.Pause(2,5);
    На подобные:
    Code (CSharp):
    1. Thread.Sleep(Global.Classes.rnd.Next(2,5)*100);
    В общем, в тех сниппетах используется кастомный метод паузы из общего кода, на него и ругается компилятор, если тот отсутствует. :-)
     
  25. Juniorcpa

    Juniorcpa Client

    Joined:
    May 27, 2014
    Messages:
    1,159
    Likes Received:
    511
    Логика в целом понятна, жаль что без знаний адаптировать под свой будущий проект пока не выходит.
     
  26. Juniorcpa

    Juniorcpa Client

    Joined:
    May 27, 2014
    Messages:
    1,159
    Likes Received:
    511
    А вот теперь выходит :-) По Вашим примерам получается :-)
     
    LaGir likes this.
  27. Roman48

    Roman48 Client

    Joined:
    Feb 28, 2016
    Messages:
    83
    Likes Received:
    7
    Как вставить переменную
    1. //Делаем прокрутку на 500 пикселей ВНИЗ (по y)
    2. instance.ActiveTab.FullEmulationMouseWheel(project.Variables["test"].Value);
    3. //Делаем прокрутку на 500 пикселей ВВЕРХ (по y)
    4. instance.ActiveTab.FullEmulationMouseWheel(0, -500)
    5. Так вставляю не работает
     
  28. esouldy

    esouldy Client

    Joined:
    Feb 28, 2016
    Messages:
    184
    Likes Received:
    85
     
  29. Roman48

    Roman48 Client

    Joined:
    Feb 28, 2016
    Messages:
    83
    Likes Received:
    7
    НЕ работает так.
    [​IMG]
     
    Last edited: Apr 6, 2018
    Viking01 likes this.
  30. Viking01

    Viking01 Client

    Joined:
    Aug 19, 2017
    Messages:
    33
    Likes Received:
    7
    о, как раз начал разбираться с эмуляцией) с новой версией ничего не изменилось по "очеловечиванию" движения мышки?
     

Пользователи просматривающие тему (Пользователей: 0, Гостей: 0)