Оптимизация скорости шаблона через избавление от пауз

amyboose

Client
Регистрация
21.04.2016
Сообщения
2 312
Благодарностей
1 191
Баллы
113
82420

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

Добрый день всем и хочу вам представить шаблон. Он ускорить рутинную работу с ZennoPoster.

Часто бывает такое, что шаблон буквально усеян паузами. Делается это по банальной причине - подождать пока гарантированно загрузится элемент. Ещё один вариант решения проблемы с ожиданием элементов на странице - это кубик свойства действия:
82423


При подходе с паузами всегда возникает лишнее время ожидания, а при использовании кубика нельзя задать необходимые параметры, как, например, дождаться пока у элемента размер будет больше 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']")));
В коде устанавливается таймаут ожидания в 15 секунд. Если за 15 секунд элемент не будет найден, то шаблон сгенерирует ошибку. Если элемент будет найден, то код сразу завершит выполнение и удачным выходом. Таймаут проверки устанавливался в 1 секунду, который можно изменить на свой.

С первого взгляда код кажется не меньше кода с циклом for. Но из всего кода большая часть только подготовительная, а основной является следующая:
C#:
IHtmlElement he = waiter.Until(ExpectedConditions<ITab>.ElementExists(By.XPath("//div[@class='recaptcha-checkbox-checkmark']")));
Давайте теперь нажмем на кнопку и подождем пока стиль изменится на "visibility: visible". Я только дополню прошлый код:
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')]")));
Видно, что код ожидания занимает всего 1 строку, что очень удобно.

Далее рассмотрим более сложный вариант, когда рассматривается сразу несколько вариантов. Код сопроводил комментариями.
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;
});
 
Категория
Полезно
Номер конкурса шаблонов
Восьмой конкурс шаблонов
Уровень сложности
Продвинутый

Вложения

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

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

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

kagorec

Client
Регистрация
24.08.2013
Сообщения
979
Благодарностей
523
Баллы
93
Не создает ли это большой нагрузки на процессор?
п.с. В одном популярном парсере подобные проверки (на появление элемента) отжирает неплохо ресурсы при 5 потоках и более.
 
  • Спасибо
Реакции: Juniorcpa

WWWorm

Client
Регистрация
29.08.2015
Сообщения
57
Благодарностей
15
Баллы
8
Не создает ли это большой нагрузки на процессор?
п.с. В одном популярном парсере подобные проверки (на появление элемента) отжирает неплохо ресурсы при 5 потоках и более.
Как по мне, так пусть будет на 5 потоков меньше, но все они отработают корректно.
 

amyboose

Client
Регистрация
21.04.2016
Сообщения
2 312
Благодарностей
1 191
Баллы
113
Не создает ли это большой нагрузки на процессор?
п.с. В одном популярном парсере подобные проверки (на появление элемента) отжирает неплохо ресурсы при 5 потоках и более.
Сложно оценить этот вопрос.
Я использую паузы в 1 секунду. Даже если за 10 секунд сделает 10 проверок, то это лучше, чем ждать, например, дополнительные 5-10 секунд, во время которых в браузере может выполняться всё что угодно и пожирать больше ресурсов, чем просто 10 раз проверить элемент.
 
  • Спасибо
Реакции: kagorec

bitardenko

Client
Регистрация
27.12.2020
Сообщения
91
Благодарностей
73
Баллы
18
Всё это мучило и меня. Я начал использовать циклы в следующем стиле:
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);
}
Да, это намного лучше, чем другие варианты, но остаётся другая проблема и состоит в том, что чем больше пишешь кода, тем сложнее контролировать код и тем сложнее не допустить ошибку. Код становится большим и громоздким.
Ну вот я прописал подобный цикл в общем коде и точно так же вызываю его в 1 строчку. Что-то не вижу каких-то преимуществ этого метода над простым циклом.
 

amyboose

Client
Регистрация
21.04.2016
Сообщения
2 312
Благодарностей
1 191
Баллы
113
Ну вот я прописал подобный цикл в общем коде и точно так же вызываю его в 1 строчку. Что-то не вижу каких-то преимуществ этого метода над простым циклом.
Представь, у тебя таких случаев штук 50 во всем шаблоне. Ты можешь их размещать в кубике, можешь в общем кода, но какая разница где ты их размещаешь, если код все равно есть?
Можно сравнить с библиотекой - ведь её тоже можно вызвать 1 строкой, но это же не означает, что код, лежащий внутри не нужен.
 

Astraport

Client
Регистрация
01.05.2015
Сообщения
4 983
Благодарностей
4 433
Баллы
113

bitardenko

Client
Регистрация
27.12.2020
Сообщения
91
Благодарностей
73
Баллы
18
Представь, у тебя таких случаев штук 50 во всем шаблоне. Ты можешь их размещать в кубике, можешь в общем кода, но какая разница где ты их размещаешь, если код все равно есть?
Можно сравнить с библиотекой - ведь её тоже можно вызвать 1 строкой, но это же не означает, что код, лежащий внутри не нужен.
Ну так а в чем суть? Может я чего-то не понимаю? К примеру есть 2 варианта : простой цикл записанный в общий код, варианты которого наверняка многие давно используют
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);

}
Вызываемый как-то так CheckAndClick(instance.ActiveTab, xpath)
И ваш вариант
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']")));

he.ClickFull();
Может я, опять же, чего-то не понимаю, но выполняют они одну функцию - чекают и кликают и в чем же преимущества второго над первым?
 

amyboose

Client
Регистрация
21.04.2016
Сообщения
2 312
Благодарностей
1 191
Баллы
113
Ну так а в чем суть? Может я чего-то не понимаю? К примеру есть 2 варианта : простой цикл записанный в общий код, варианты которого наверняка многие давно используют
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);

}
Вызываемый как-то так CheckAndClick(instance.ActiveTab, xpath)
И ваш вариант
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']")));

he.ClickFull();
Может я, опять же, чего-то не понимаю, но выполняют они одну функцию - чекают и кликают и в чем же преимущества второго над первым?
В том, что тот пример с циклом не является универсальным. В коде постоянно с каждым элементов приходится делать разные действия и поэтому для каждого такого действия придется расписывать свой отдельный цикл.
Я же предлагаю избавиться от всех этих for и пауз, сосредоточиться только на нужном функционале, который применим везде.
Не надо будет новые методы создавать никакие
 

BAZAg

Client
Регистрация
08.11.2015
Сообщения
1 787
Благодарностей
2 453
Баллы
113
Если я правильно понял, то под избавлением от пауз имеется ввиду скрытие пауз с глаз долой так, чтобы мои глаза их не видели, но, под капотом всё же паузы используются?
Просто из названия темы, ожидал всё же что-то типа async/await и прям подумал, неужели кто-то смог их подружить для всех основных действий...

В любом случае спасибо за полезный материал!
 
  • Спасибо
Реакции: DevOps

amyboose

Client
Регистрация
21.04.2016
Сообщения
2 312
Благодарностей
1 191
Баллы
113
Если я правильно понял, то под избавлением от пауз имеется ввиду скрытие пауз с глаз долой так, чтобы мои глаза их не видели, но, под капотом всё же паузы используются?
Просто из названия темы, ожидал всё же что-то типа async/await и прям подумал, неужели кто-то смог их подружить для всех основных действий...

В любом случае спасибо за полезный материал!
Да, паузы скрыты. Async/await тут можно было бы прицепить к скрипту, который мог выполняться в асинхронном процессе и потом его ожидать, но это уже совсем иной уровень магии.
Многим до Хогвартса рановато тут, поэтому выложил простое, более-менее понятное для чуть-чуть понимающих C#решение
 
  • Спасибо
Реакции: BAZAg

BAZAg

Client
Регистрация
08.11.2015
Сообщения
1 787
Благодарностей
2 453
Баллы
113
Да, паузы скрыты. Async/await тут можно было бы прицепить к скрипту, который мог выполняться в асинхронном процессе и потом его ожидать, но это уже совсем иной уровень магии.
Многим до Хогвартса рановато тут, поэтому выложил простое, более-менее понятное для чуть-чуть понимающих C#решение
Я без критики (мало ли вдруг так воспринял).
Просто прочитал заголовок темы, думаю всё, счас изучу грааль и магию асинков.
Материал крутой, и однозначно многим будет полезным (просто подобный подход я также применяю, из-за чего и переспросил, чтобы что-то не упустить).
 

Zedx

Client
Регистрация
12.06.2018
Сообщения
1 346
Благодарностей
910
Баллы
113
Спасибо, очень полезная фича.
 

TheBoss

Client
Регистрация
30.03.2015
Сообщения
529
Благодарностей
194
Баллы
43
Привет! Можешь плиз перезалить шаблон

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

Добрый день всем и хочу вам представить шаблон. Он ускорить рутинную работу с ZennoPoster.

Часто бывает такое, что шаблон буквально усеян паузами. Делается это по банальной причине - подождать пока гарантированно загрузится элемент. Ещё один вариант решения проблемы с ожиданием элементов на странице - это кубик свойства действия:
Посмотреть вложение 82423

При подходе с паузами всегда возникает лишнее время ожидания, а при использовании кубика нельзя задать необходимые параметры, как, например, дождаться пока у элемента размер будет больше 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']")));
В коде устанавливается таймаут ожидания в 15 секунд. Если за 15 секунд элемент не будет найден, то шаблон сгенерирует ошибку. Если элемент будет найден, то код сразу завершит выполнение и удачным выходом. Таймаут проверки устанавливался в 1 секунду, который можно изменить на свой.

С первого взгляда код кажется не меньше кода с циклом for. Но из всего кода большая часть только подготовительная, а основной является следующая:
C#:
IHtmlElement he = waiter.Until(ExpectedConditions<ITab>.ElementExists(By.XPath("//div[@class='recaptcha-checkbox-checkmark']")));
Давайте теперь нажмем на кнопку и подождем пока стиль изменится на "visibility: visible". Я только дополню прошлый код:
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')]")));
Видно, что код ожидания занимает всего 1 строку, что очень удобно.

Далее рассмотрим более сложный вариант, когда рассматривается сразу несколько вариантов. Код сопроводил комментариями.
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;
});
Спасибо!
 

Gooldbee

Client
Регистрация
16.05.2019
Сообщения
224
Благодарностей
25
Баллы
28
Я не могу проверить ваш шаблон =(

Тип Время Сообщение
09:32:14 Компиляция кода проекта Ошибка в действии "CS0006" "Metadata file 'C:\Program Files\ZennoLab\RU\ZennoPoster Pro V7\7.5.1.0\Progs\ExternalAssemblies\ZennoEmulator.dll' could not be found".
 

dimafatality

Client
Регистрация
19.01.2014
Сообщения
267
Благодарностей
255
Баллы
63
  • Спасибо
Реакции: Gooldbee

Gooldbee

Client
Регистрация
16.05.2019
Сообщения
224
Благодарностей
25
Баллы
28
Закинь *.dll из архива в папку:

C:\Program Files\ZennoLab\RU\ZennoPoster Pro V7\7.5.1.0\Progs\ExternalAssemblies\
Твой работает, а к себе не могу =(
при добавление в GAG
Тип Время Сообщение
03:27:44 Подключение сборки к проекту C:\Program Files\ZennoLab\RU\ZennoPoster Pro V7\7.5.1.0\Progs\ExternalAssemblies\ZennoEmulator.dll не является .Net сборкой или не возможно получить доступ к сборке
03:27:44 "Подключение сборки к проекту System.Exception: Выдано исключение типа ""System.Exception"".
в ZennoLab.ProjectMaker.Controls.ProjectEditor.ProjectBar.StaticBlockSettings.GACReferences.yWYCUTOvDL(Object , OkButtonClickArgs )"
 

Gooldbee

Client
Регистрация
16.05.2019
Сообщения
224
Благодарностей
25
Баллы
28
Разобрался) спасибо) а как добавить элемент не
ElementExists(By.XPath
а кнопу через конструктор действий? btn_payment_method\ header-btns__item\ header-btns__type
XPath меняется каждый раз у меня
у меня элемент с таким кодом //*[@id="marketFilter_3"] не как н могу добавить (
 
Последнее редактирование:

amyboose

Client
Регистрация
21.04.2016
Сообщения
2 312
Благодарностей
1 191
Баллы
113
Разобрался) спасибо) а как добавить элемент не
ElementExists(By.XPath
а кнопу через конструктор действий? btn_payment_method\ header-btns__item\ header-btns__type
XPath меняется каждый раз у меня
у меня элемент с таким кодом //*[@id="marketFilter_3"] не как н могу добавить (
Нужно ждать пока элемент исчезнет?
 

Gooldbee

Client
Регистрация
16.05.2019
Сообщения
224
Благодарностей
25
Баллы
28
Нужно ждать пока элемент исчезнет?
Пока появится, решил вопрос конвертацией зерно в с# , у меня почему то при запуске в прожекте всегда ругается на отсутствие dll ZennoEmulator или как там, хотя в папке есть и везде указано
 

amyboose

Client
Регистрация
21.04.2016
Сообщения
2 312
Благодарностей
1 191
Баллы
113
Пока появится, решил вопрос конвертацией зерно в с# , у меня почему то при запуске в прожекте всегда ругается на отсутствие dll ZennoEmulator или как там, хотя в папке есть и везде указано
Ошибка при входе встречается у всех. Причина в том, что к этой библиотеке привязано с десяток разных библиотек и у каждой своя цель. Чтобы не использовать лишний функционал я дал только 3 самые необходимые, а остальные использую я сам
 
  • Спасибо
Реакции: Gooldbee

Gooldbee

Client
Регистрация
16.05.2019
Сообщения
224
Благодарностей
25
Баллы
28
Ошибка при входе встречается у всех. Причина в том, что к этой библиотеке привязано с десяток разных библиотек и у каждой своя цель. Чтобы не использовать лишний функционал я дал только 3 самые необходимые, а остальные использую я сам
Понял, спасибо за шаблон, сократил время на 15 секунд это большой результат =) при выполнение в 45 секунд (ставка)
 

amyboose

Client
Регистрация
21.04.2016
Сообщения
2 312
Благодарностей
1 191
Баллы
113
Понял, спасибо за шаблон, сократил время на 15 секунд это большой результат =) при выполнение в 45 секунд (ставка)
Да давно бы все пользовались этим решением и значительно ускорили свои шаблоны.
Статические паузы - это каменный век
 

Gooldbee

Client
Регистрация
16.05.2019
Сообщения
224
Благодарностей
25
Баллы
28
Да давно бы все пользовались этим решением и значительно ускорили свои шабло
Статические паузы - это каменный век
На счёт статических согласен.. Было бы круто если бы твоё решение добавили в кубик как обнову)
 

Phoenix78

Client
Read only
Регистрация
06.11.2018
Сообщения
11 790
Благодарностей
5 720
Баллы
113
На счёт статических согласен.. Было бы круто если бы твоё решение добавили в кубик как обнову)
зачем это, если в зенке давным давно есть ожидание элемента ?
Автор топика в самом начале написал про этот кубик.

85662


Вообще не понимаю про какие статичные паузы тут обсуждают, если всегда были доступны динамические :bm:
 

ZennoCat

Client
Регистрация
06.01.2020
Сообщения
45
Благодарностей
14
Баллы
8
зачем это, если в зенке давным давно есть ожидание элемента ?
Автор топика в самом начале написал про этот кубик.

Посмотреть вложение 85662

Вообще не понимаю про какие статичные паузы тут обсуждают, если всегда были доступны динамические :bm:
это если ты знаешь что ждать, для иных случаев статика).
 

Phoenix78

Client
Read only
Регистрация
06.11.2018
Сообщения
11 790
Благодарностей
5 720
Баллы
113
это если ты знаешь что ждать, для иных случаев статика).
для иных случаев, я пользуюсь динамичным циклом ожидания статики на странице. в течении 40 секунд жду пока на странице не будет изменений в течении 4-10 секунд. в большинстве случаев это быстрее получается, чем ждать статику в 40-60 секунд.
 
  • Спасибо
Реакции: ZennoCat

ZennoCat

Client
Регистрация
06.01.2020
Сообщения
45
Благодарностей
14
Баллы
8
для иных случаев, я пользуюсь динамичным циклом ожидания статики на странице. в течении 40 секунд жду пока на странице не будет изменений в течении 4-10 секунд. в большинстве случаев это быстрее получается, чем ждать статику в 40-60 секунд.
можешь поделится реализацией?
 

Phoenix78

Client
Read only
Регистрация
06.11.2018
Сообщения
11 790
Благодарностей
5 720
Баллы
113
можешь поделится реализацией?
C#:
int max_k = 7;      // максимум итераций ожидания стабильности
int sleep = 1000;
//----
int k = 0;
string temp_html = "";
for (int i = 0; i<max_k*6; i++) {
    try {
        HtmlElement he = instance.ActiveTab.FindElementByXPath(@"//html", 0);
        if (he.IsVoid)         {
            Thread.Sleep(sleep);     continue ;
        }
        if (he.Width <= 0)         {
            Thread.Sleep(sleep);     continue ;
        }
        if (k >= max_k) return 0;
        if (he.InnerHtml == temp_html)         {
            project.SendInfoToLog("нет изменений");
            k++;
        } else         {
            project.SendInfoToLog("есть изменения");
            k = 0;
            temp_html = he.InnerHtml;
        }
    } catch { }
    Thread.Sleep(sleep);
}
 
  • Спасибо
Реакции: ZennoCat

ZennoCat

Client
Регистрация
06.01.2020
Сообщения
45
Благодарностей
14
Баллы
8
C#:
int max_k = 7;      // максимум итераций ожидания стабильности
int sleep = 1000;
//----
int k = 0;
string temp_html = "";
for (int i = 0; i<max_k*6; i++) {
    try {
        HtmlElement he = instance.ActiveTab.FindElementByXPath(@"//html", 0);
        if (he.IsVoid)         {
            Thread.Sleep(sleep);     continue ;
        }
        if (he.Width <= 0)         {
            Thread.Sleep(sleep);     continue ;
        }
        if (k >= max_k) return 0;
        if (he.InnerHtml == temp_html)         {
            project.SendInfoToLog("нет изменений");
            k++;
        } else         {
            project.SendInfoToLog("есть изменения");
            k = 0;
            temp_html = he.InnerHtml;
        }
    } catch { }
    Thread.Sleep(sleep);
}
Спасибо, очень понравилась реализация). Сейчас попробую использовать в своем шаблоне
 
Последнее редактирование:

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