- Регистрация
- 21.04.2016
- Сообщения
- 2 312
- Благодарностей
- 1 191
- Баллы
- 113
Это ждун и он ждет, пока в твоём шаблоне закончится пауза и шаблон наконец продолжит зарабатывать тебе копеечку на хлеб с красной икрой.
Добрый день всем и хочу вам представить шаблон. Он ускорить рутинную работу с ZennoPoster.
Часто бывает такое, что шаблон буквально усеян паузами. Делается это по банальной причине - подождать пока гарантированно загрузится элемент. Ещё один вариант решения проблемы с ожиданием элементов на странице - это кубик свойства действия:
При подходе с паузами всегда возникает лишнее время ожидания, а при использовании кубика нельзя задать необходимые параметры, как, например, дождаться пока у элемента размер будет больше 50 пикселей.
Всё это мучило и меня. Я начал использовать циклы в следующем стиле:
C#:
for (int i = 0; ;i++)
{
HtmlElement heSubmit = instance.ActiveTab.FindElementByXPath(@"//button[@class='submit", 0);
if (!heSubmit.IsVoid)
{
heSubmit.RiseEvent("click", "Full");
break;
}
if (i > 5)
throw new Exception("Кнопка сабмит не найдена");
Thread.Sleep(1000);
}
Поэтому я искал альтернативное решение и оно нашлось. Я реализовал подход из библиотеки Selenium с ожиданием элементов, который очень хорошо показал себя на практике, оказался очень удобным и теперь я его использую повсеместно.
Давайте рассмотрим его подробнее в виде самого простого кода. К коду приложил комментарии
C#:
//Создаем браузер
IBrowser browser = new ZennoBrowser(instance, project);
//Создаем ожидающий элемент, в каждом кубике создается всего 1 раз
BrowserWait<ITab> waiter = new BrowserWait<ITab>(browser.ActiveTab, TimeSpan.FromSeconds(15))
{
//Устанавливаем таймаут проверки страницы, по умолчанию - 1 секунда
//Можно закомментировать
PollingInterval = TimeSpan.FromSeconds(1)
};
//Ждем пока html элемент появится и получаем его
IHtmlElement he = waiter.Until(ExpectedConditions<ITab>.ElementExists(By.XPath("//div[@class='recaptcha-checkbox-checkmark']")));
С первого взгляда код кажется не меньше кода с циклом for. Но из всего кода большая часть только подготовительная, а основной является следующая:
C#:
IHtmlElement he = waiter.Until(ExpectedConditions<ITab>.ElementExists(By.XPath("//div[@class='recaptcha-checkbox-checkmark']")));
C#:
//Нажимаем на кнопку
he.ClickFull();
//Ждем пока появится элемент с нужным параметром
IHtmlElement heWindows = waiter.Until(ExpectedConditions<ITab>.ElementExists(By.XPath("//div[contains(@style, 'visibility: visible')]/div/iframe[starts-with(@src, 'https://www.google.com/recaptcha/api2')]")));
Далее рассмотрим более сложный вариант, когда рассматривается сразу несколько вариантов. Код сопроводил комментариями.
C#:
IBrowser browser = new ZennoBrowser(instance, project);
BrowserWait<ITab> waiter = new BrowserWait<ITab>(browser.ActiveTab, TimeSpan.FromSeconds(15))
{
PollingInterval = TimeSpan.FromSeconds(1)
};
IHtmlElement heSiteKey = null;
IHtmlElement heRecaptchaSubmit = null;
IHtmlElement heSendCode = null;
waiter.Until(condition =>
{
//Если найдена кнопка с просьбой перезагрузить страницу, то генерируем ошибку
IHtmlElement heReloadPage = browser.ActiveTab.FindElement(Info.ReloadPageXPath);
if (heReloadPage != null)
throw new Exception("Страница с рекапчей не открылась");
//Если на странице не появилась рекапча, а сразу появился нужный нам блок с запросом телефона, то удачно завершаем
//return true как раз означает удачное завершение цикла
heSendCode = browser.ActiveTab.FindElement(Info.SendCodeXPath);
if (heSendCode != null)
return true;
//Проверяем на наличие рекапчи. Если её нету, то ждем и начинаем сначала весь цикл проверок
//return false как раз означает, что нужно начинать все проверки с начала
heSiteKey = browser.ActiveTab.FindElement(Info.SiteKeyXPath);
if (heSiteKey == null)
return false;
//Проверяем на наличие кнопки submit. Если её нету, то ждем и начинаем сначала весь цикл проверок
//return false как раз означает, что нужно начинать все проверки с начала
heRecaptchaSubmit = browser.ActiveTab.FindElement(Info.RecaptchaSubmitXPath);
if (heRecaptchaSubmit == null)
return false;
//В данном случае все необходимые условия выполнены, поэтому можем спокойно завершить проверки
//return true как раз означает удачное завершение цикла
return true;
});
1) возвращается false, если выполнены не все условия, ждёт и потом идет ещё на следующий круг цикла, пока не достигнет ошибки или true
2) генерируется ошибка, если дальнейшее ожидание не имеет смысла
3) возвращается true, когда все условия выполнены и выходит из цикла.
Таким образом можно проектировать даже сложные конструкции ожидания.
Этот пример вырезан из моего кода, поэтому не пытайтесь его повторить, так как он выдаст ошибку из-за моих упрощений в виде замены By.XPath на Info.ReloadPageXPath и подобных.
Напоследок ещё один пример. Тут код начинает грузить страницу и сразу же проверяет в быстром режиме пока основной фрейм не загрузится. Таймаут проверок - 100 мс.
C#:
instance.ActiveTab.Navigate("https://www.google.com/recaptcha/api2/demo");
IBrowser browser = new ZennoBrowser(instance, project);
BrowserWait<ITab> waiter = new BrowserWait<ITab>(browser.ActiveTab, TimeSpan.FromSeconds(15))
{
PollingInterval = TimeSpan.FromMilliseconds(100)
};
waiter.Until(condition =>
{
string result = browser.ActiveTab.MainDocument.EvaluateScript("return document.readyState == 'complete';", true);
bool documentOpened = result == "true";
return documentOpened;
});
- Категория
- Полезно
- Номер конкурса шаблонов
- Восьмой конкурс шаблонов
- Уровень сложности
- Продвинутый
Вложения
-
28 МБ Просмотры: 243
Для запуска проектов требуется программа ZennoPoster или ZennoDroid.
Это основное приложение, предназначенное для выполнения автоматизированных шаблонов действий (ботов).
Подробнее...
Для того чтобы запустить шаблон, откройте нужную программу. Нажмите кнопку «Добавить», и выберите файл проекта, который хотите запустить.
Подробнее о том, где и как выполняется проект.
Последнее редактирование: