Как сделать Ожидание - пока не подгрузит Java элемент.

Gunjubasik

Client
Регистрация
30.05.2019
Сообщения
3 521
Благодарностей
1 319
Баллы
113
Доброго времени всем суток. Подскажите, пожалуйста, если на сайте на подобие Avito,VK,OLX и т.д. - у всех есть Java элемент - например вбиваешь в поиск определенные настройки(параметры) страницы - допустим сортировка по определенному товару или по цене - идет внутренняя загрузка (кружочек ожидания прямо на странице) java элемента (т.е. сортировка по заданным параметрам) и вот в этом время, бот уже фигачит парсить инфу на сайте по заданным им ранее параметрам, но страница то еще не подгрузила данные, которые мы собрались парсить - в результате получаем - бот проходит блоки задач и не выполняем их. Как мне сделать так, что бы бот понимал - Идет подгрузка настройки страницы? - Ждем пока пройдет. Прошла? - Ну тогда идем по кубикам дальше. Думал просто паузами лечить это - но каждый раз, вбивая коррективы в настройки - прогрузка данных страницы - разная....

Заранее, очень благодарен за помощь!

P.S: Пытался отследить по определенным измененным элементам при подгрузке после настроек - но никак не могу зацепиться за что-либо.
 
Последнее редактирование:

ibred

Client
Регистрация
04.04.2015
Сообщения
3 835
Благодарностей
3 552
Баллы
113
Сохраняете DOM страницы до появления нужного элемента и после его появления.
Сравниваете два текстовых файла и находите различие. Далее создаёте цикл, который будет чекать DOM на эту разницу.

P.S: Пытался отследить по определенным измененным элементам при подгрузке после настроек
Если Вы так уже делали и считаете, что вариантов больше нет - присылайте конкретный пример, будем смотреть.
 
  • Спасибо
Реакции: Gunjubasik и Sergodjan

Gunjubasik

Client
Регистрация
30.05.2019
Сообщения
3 521
Благодарностей
1 319
Баллы
113
Cпасибо, я попробую.И еще мне нужна помощь в одном случае парсинга. Есть страница с товарами в виде сетки. Количество товаров - пытаюсь парсить (через конструктор регулярных выражений) по цене, которая изображена на товаре. Но самое интересноe, что если заходить несколько раз и смотреть другие товары на этой же таблице - парсить неудается, так как меняются элементы, от которых я отталкиваюсь. Есть ли возможность указать, в регулярном выражении, что допустим до текста который мы ищем, определенный элемент может меняться? Или например добавить в конструктор регулярных выражений - подобную строчку, которая позволит более гибко настраивать парс?
1 Вариант:
(?<=<!----><!----><dm-currency-icon\ _ngcontent-dmarket-c17=""\ class="ng-star-inserted"><span\ class="o-currencies--USD"></span></dm-currency-icon>).*?(?=</span></strong>)
2 Вариант:
(?<=<!----><!----><dm-currency-icon\ _ngcontent-dmarket-c20=""\ class="ng-star-inserted"><span\ class="o-currencies--USD"></span></dm-currency-icon>).*?(?=\ </span></strong><!----><!----><!---->)
3 Вариант:
(?<=<asset-price-icon\ _ngcontent-dmarket-c22=""\ _nghost-dmarket-c23=""\ class="ng-star-inserted"><!----></asset-price-icon><span\ _ngcontent-dmarket-c22=""\ class="c-asset__priceNumber"><!----><!----><dm-currency-icon\ _ngcontent-dmarket-c22=""\ class="ng-star-inserted"><span\ class="o-currencies--USD"></span></dm-currency-icon>).*?(?=\ </span></strong><!----><!----><!---->)

Сохраняете DOM страницы до появления нужного элемента и после его появления.
Сравниваете два текстовых файла и находите различие. Далее создаёте цикл, который будет чекать DOM на эту разницу.


Если Вы так уже делали и считаете, что вариантов больше нет - присылайте конкретный пример, будем смотреть.
 

BAZAg

Client
Регистрация
08.11.2015
Сообщения
1 787
Благодарностей
2 453
Баллы
113
Когда какие-то данные подгружаются на страничке - сайт отправляет какие-то запросы.
А в Зеннопостере есть такая штука, которая позволяет отслеживать запросы.
И вот, уже исходя из этого можно сообразить следующую логику - берем все запросы в список.
Дальше - ждём например 5 секунд.
Снова считаем количество запросов - если количество больше 0, значит сайт ещё что-то куда-то шлёт - ждём дальше.
На следующей итерации цикла - обратно получаем список запросов - если есть - ждем, если нет - увеличиваем счётчик.
Если допустим за 3-4 итерации оказалось что запросов никаких сайт не отправлял - можем сделать вывод, что уже все данные получены - и выходим с цикла.
Понятно, конечно, что если дальше, после получения данных ещё производится какая-то обработка (например сортировка большого массива) скриптами на страничке - тогда нужно после этого дать дополнительное ожидание, после чего уже искать появился ли нужный элемент с нужными данными.

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

Также, не претендую на факт, что это самый идеально хороший вариант, но, для моих целей данный код работает как надо.
C#:
Random rand = new Random();
bool check = false;
List<TrafficItem> traffic = instance.ActiveTab.GetTraffic().ToList();
int count_tr = 0;
for(int y=0; y < 20; y++) {              
    traffic = instance.ActiveTab.GetTraffic().ToList();
     //project.SendInfoToLog(string.Format(@"{0} {1} {2}", traffic.Count, count_tr, check), true);
    System.Threading.Thread.Sleep(rand.Next(5, 10) * 100);
    if(traffic.Count > 0) {
        System.Threading.Thread.Sleep(rand.Next(3, 5) * 1000);
        count_tr = 0;
        continue;
    }
    else {
        System.Threading.Thread.Sleep(rand.Next(2, 5) * 1000);
        count_tr++;
    }
    if(count_tr > 3) check = true;
        if(check) break;      
    }  
return check;
 

Gunjubasik

Client
Регистрация
30.05.2019
Сообщения
3 521
Благодарностей
1 319
Баллы
113
Спасибо, большое. Но можно более детально, как отслеживать запросы и как обращаться с кодом, предложенным вами? Так как я не силен в кодировке.

Когда какие-то данные подгружаются на страничке - сайт отправляет какие-то запросы.
А в Зеннопостере есть такая штука, которая позволяет отслеживать запросы.
И вот, уже исходя из этого можно сообразить следующую логику - берем все запросы в список.
Дальше - ждём например 5 секунд.
Снова считаем количество запросов - если количество больше 0, значит сайт ещё что-то куда-то шлёт - ждём дальше.
На следующей итерации цикла - обратно получаем список запросов - если есть - ждем, если нет - увеличиваем счётчик.
Если допустим за 3-4 итерации оказалось что запросов никаких сайт не отправлял - можем сделать вывод, что уже все данные получены - и выходим с цикла.
Понятно, конечно, что если дальше, после получения данных ещё производится какая-то обработка (например сортировка большого массива) скриптами на страничке - тогда нужно после этого дать дополнительное ожидание, после чего уже искать появился ли нужный элемент с нужными данными.

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

Также, не претендую на факт, что это самый идеально хороший вариант, но, для моих целей данный код работает как надо.
C#:
Random rand = new Random();
bool check = false;
List<TrafficItem> traffic = instance.ActiveTab.GetTraffic().ToList();
int count_tr = 0;
for(int y=0; y < 20; y++) {             
    traffic = instance.ActiveTab.GetTraffic().ToList();
     //project.SendInfoToLog(string.Format(@"{0} {1} {2}", traffic.Count, count_tr, check), true);
    System.Threading.Thread.Sleep(rand.Next(5, 10) * 100);
    if(traffic.Count > 0) {
        System.Threading.Thread.Sleep(rand.Next(3, 5) * 1000);
        count_tr = 0;
        continue;
    }
    else {
        System.Threading.Thread.Sleep(rand.Next(2, 5) * 1000);
        count_tr++;
    }
    if(count_tr > 3) check = true;
        if(check) break;     
    } 
return check;
 

BAZAg

Client
Регистрация
08.11.2015
Сообщения
1 787
Благодарностей
2 453
Баллы
113
Спасибо, большое. Но можно более детально, как отслеживать запросы и как обращаться с кодом, предложенным вами? Так как я не силен в кодировке.
Добавить в кубик свой С#.
Результат сохранять в переменную.
Если вернёт True - значит сайт больше ничего не грузит.
Если вернет False - значит сайт всё ещё шлёт какие-то запросы.
Паузы, естественно нужно подправить под свой случай (мне обычно выставленных в коде хватает, но, бывает приходится либо у уменьшать или увеличивать).
 

Gunjubasik

Client
Регистрация
30.05.2019
Сообщения
3 521
Благодарностей
1 319
Баллы
113
А с этим помочь можете?


Добавить в кубик свой С#.
Результат сохранять в переменную.
Если вернёт True - значит сайт больше ничего не грузит.
Если вернет False - значит сайт всё ещё шлёт какие-то запросы.
Паузы, естественно нужно подправить под свой случай (мне обычно выставленных в коде хватает, но, бывает приходится либо у уменьшать или увеличивать).
 

Lord_Alfred

Client
Регистрация
09.10.2015
Сообщения
3 916
Благодарностей
3 867
Баллы
113
Где-то 3 года назад камрад @Adigen скидывал прекрасную реализацию такой проверки, вроде он не против если я поделюсь тут.

Вставить это в owncode (свой код):
C#:
public static class ZHelpers
    {
        private static string[] LoadStates = {"complete", "uninitialized", }; //Статусы которые считаем что документ загрузился
        
        /// <summary>
        /// Ожидание загрузки таба
        /// </summary>
        /// <param name="tab">Таб загрузки которого ждем</param>
        /// <param name="maxWaitMs">Максимальное ожидание в мс, по умолчанию 60 сек</param>
        public static void TabLoadWait(this Tab tab, int maxWaitMs = 60 * 1000)
        {
            maxWaitMs = maxWaitMs/2;
            //Делаем 2 захода, для точной уверенности
            for (var i = 0; i < 2; i++)
            {
                //TODO заменить на токен
                //Когда выходим
                long maxTime = DateTime.Now.Ticks + maxWaitMs * 10000;
                //Проверям на загрузку странцы пока не кончится время или мы не получим все интересующие нас данные
                do
                {
                
                // TODO: проверка прерывания
                
                    new System.Threading.ManualResetEvent(false).WaitOne(2000);
                    if (tab.IsBusy) tab.WaitDownloading();

                    //Проверяем через js document.readyState, статус всех документов на страницы
                    bool isNotComplete = false;
                    foreach (var document in tab.AllDocuments.Documents)
                    {
                        string readyState = document.EvaluateScript("return document.readyState;");
                        if (!String.IsNullOrEmpty(readyState) && !LoadStates.Contains(readyState))
                        {
                            if (readyState != "interactive" || !document.URL.StartsWith("about:",StringComparison.Ordinal))
                                isNotComplete = true;
                        }
                    }

                    // Если у всех статус complete считаем что прошли проверку
                    if (!isNotComplete)
                        break;
                }
                while (DateTime.Now.Ticks < maxTime);
            }
        }
    }
И вызывать из c# кубика с помощью:
C#:
instance.ActiveTab.TabLoadWait();
 

Gunjubasik

Client
Регистрация
30.05.2019
Сообщения
3 521
Благодарностей
1 319
Баллы
113
52431
Я верно вставил? Так как второй блок c# - куда бы я его не вставил(в виде паузы, там где нужно ждать прогрузки) - все-равно не может до конца понять, что идет прогурзка страницы. Или возможно я что-то не так делаю?
Второй блок c# должен стоять после нажатия на поиск страницы, верно? Или нужно до того?
52432

Где-то 3 года назад камрад @Adigen скидывал прекрасную реализацию такой проверки, вроде он не против если я поделюсь тут.

Вставить это в owncode (свой код):
C#:
public static class ZHelpers
    {
        private static string[] LoadStates = {"complete", "uninitialized", }; //Статусы которые считаем что документ загрузился
     
        /// <summary>
        /// Ожидание загрузки таба
        /// </summary>
        /// <param name="tab">Таб загрузки которого ждем</param>
        /// <param name="maxWaitMs">Максимальное ожидание в мс, по умолчанию 60 сек</param>
        public static void TabLoadWait(this Tab tab, int maxWaitMs = 60 * 1000)
        {
            maxWaitMs = maxWaitMs/2;
            //Делаем 2 захода, для точной уверенности
            for (var i = 0; i < 2; i++)
            {
                //TODO заменить на токен
                //Когда выходим
                long maxTime = DateTime.Now.Ticks + maxWaitMs * 10000;
                //Проверям на загрузку странцы пока не кончится время или мы не получим все интересующие нас данные
                do
                {
             
                // TODO: проверка прерывания
             
                    new System.Threading.ManualResetEvent(false).WaitOne(2000);
                    if (tab.IsBusy) tab.WaitDownloading();

                    //Проверяем через js document.readyState, статус всех документов на страницы
                    bool isNotComplete = false;
                    foreach (var document in tab.AllDocuments.Documents)
                    {
                        string readyState = document.EvaluateScript("return document.readyState;");
                        if (!String.IsNullOrEmpty(readyState) && !LoadStates.Contains(readyState))
                        {
                            if (readyState != "interactive" || !document.URL.StartsWith("about:",StringComparison.Ordinal))
                                isNotComplete = true;
                        }
                    }

                    // Если у всех статус complete считаем что прошли проверку
                    if (!isNotComplete)
                        break;
                }
                while (DateTime.Now.Ticks < maxTime);
            }
        }
    }
И вызывать из c# кубика с помощью:
C#:
instance.ActiveTab.TabLoadWait();
 

Bullet

Client
Регистрация
16.12.2015
Сообщения
186
Благодарностей
19
Баллы
18
у меня тоже все время пишет, что все ОК. Хоть первый, хоть второй вариант кода
 

Gunjubasik

Client
Регистрация
30.05.2019
Сообщения
3 521
Благодарностей
1 319
Баллы
113
у меня тоже все время пишет, что все ОК. Хоть первый, хоть второй вариант кода
Периодически работает этот:
C#:
Random rand = new Random();
bool check = false;
List<TrafficItem> traffic = instance.ActiveTab.GetTraffic().ToList();
int count_tr = 0;
for(int y=0; y < 20; y++) {             
    traffic = instance.ActiveTab.GetTraffic().ToList();
     //project.SendInfoToLog(string.Format(@"{0} {1} {2}", traffic.Count, count_tr, check), true);
    System.Threading.Thread.Sleep(rand.Next(5, 10) * 100);
    if(traffic.Count > 0) {
        System.Threading.Thread.Sleep(rand.Next(3, 5) * 1000);
        count_tr = 0;
        continue;
    }
    else {
        System.Threading.Thread.Sleep(rand.Next(2, 5) * 1000);
        count_tr++;
    }
    if(count_tr > 3) check = true;
        if(check) break;     
    } 
return check;
Но только иногда до конца справляется.))) Завершает то позже нужного, то раньше.)))
 

BAZAg

Client
Регистрация
08.11.2015
Сообщения
1 787
Благодарностей
2 453
Баллы
113
Но только иногда до конца справляется.))) Завершает то позже нужного, то раньше.)))
Данный код считает запросы - если есть хотя бы 1 запрос - за последних 3-5 секунд - ожидает.
И так повторяет 20 раз.
Но, если на сайте постоянно что-то грузится - тогда он выйдет по успеху - проверяйте нужные данные на страничке - если их нет - возвращайтесь дальше на данный кубик.
Также совсем не объязательно дожидаться всех запросов - возможно есть смысл увеличить значение и прекращать, if(traffic.Count > 3).


Данный код не проверяет выполнение яваскрипта - и если какие-то данные получаются - то возможно есть смысл дать дополнительно несколько секунд ожидания на отработку запроса.
Или... Изучать более тщательно сайт, чтобы понять в чём именно на этом сайте проблема.
 
  • Спасибо
Реакции: Gunjubasik

Bullet

Client
Регистрация
16.12.2015
Сообщения
186
Благодарностей
19
Баллы
18
Объединил оба решения - вроде бы стало стабильнее ловить
 

Bullet

Client
Регистрация
16.12.2015
Сообщения
186
Благодарностей
19
Баллы
18
Не смотря на оффтоп, может есть еще какие то действенные решения, как ловить исполнение Javascript? Трафик в этот момент не передается, а может висеть какой то индикатор проегресса, как ожидание отдачи данных.
 

Gunjubasik

Client
Регистрация
30.05.2019
Сообщения
3 521
Благодарностей
1 319
Баллы
113
Подскажите, пожалуйста, вот я поймал get запрос, который нужно ожидать, что бы понять, что страница прогрузилась - есть ли возможность вставить часть ссылки GET запроса (Например: https://denvery.com/exchange/...) - что бы этот код ожидания, ждал именно get запрос, URL у которого с таким началом (Например: https://denvery.com/exchange/...)?

Где-то 3 года назад камрад @Adigen скидывал прекрасную реализацию такой проверки, вроде он не против если я поделюсь тут.

Вставить это в owncode (свой код):
C#:
public static class ZHelpers
    {
        private static string[] LoadStates = {"complete", "uninitialized", }; //Статусы которые считаем что документ загрузился
    
        /// <summary>
        /// Ожидание загрузки таба
        /// </summary>
        /// <param name="tab">Таб загрузки которого ждем</param>
        /// <param name="maxWaitMs">Максимальное ожидание в мс, по умолчанию 60 сек</param>
        public static void TabLoadWait(this Tab tab, int maxWaitMs = 60 * 1000)
        {
            maxWaitMs = maxWaitMs/2;
            //Делаем 2 захода, для точной уверенности
            for (var i = 0; i < 2; i++)
            {
                //TODO заменить на токен
                //Когда выходим
                long maxTime = DateTime.Now.Ticks + maxWaitMs * 10000;
                //Проверям на загрузку странцы пока не кончится время или мы не получим все интересующие нас данные
                do
                {
            
                // TODO: проверка прерывания
            
                    new System.Threading.ManualResetEvent(false).WaitOne(2000);
                    if (tab.IsBusy) tab.WaitDownloading();

                    //Проверяем через js document.readyState, статус всех документов на страницы
                    bool isNotComplete = false;
                    foreach (var document in tab.AllDocuments.Documents)
                    {
                        string readyState = document.EvaluateScript("return document.readyState;");
                        if (!String.IsNullOrEmpty(readyState) && !LoadStates.Contains(readyState))
                        {
                            if (readyState != "interactive" || !document.URL.StartsWith("about:",StringComparison.Ordinal))
                                isNotComplete = true;
                        }
                    }

                    // Если у всех статус complete считаем что прошли проверку
                    if (!isNotComplete)
                        break;
                }
                while (DateTime.Now.Ticks < maxTime);
            }
        }
    }
И вызывать из c# кубика с помощью:
C#:
instance.ActiveTab.TabLoadWait();
 

Roman48

Client
Регистрация
28.02.2016
Сообщения
2 058
Благодарностей
745
Баллы
113
Где-то 3 года назад камрад @Adigen скидывал прекрасную реализацию такой проверки, вроде он не против если я поделюсь тут.

Вставить это в owncode (свой код):
C#:
public static class ZHelpers
    {
        private static string[] LoadStates = {"complete", "uninitialized", }; //Статусы которые считаем что документ загрузился
       
        /// <summary>
        /// Ожидание загрузки таба
        /// </summary>
        /// <param name="tab">Таб загрузки которого ждем</param>
        /// <param name="maxWaitMs">Максимальное ожидание в мс, по умолчанию 60 сек</param>
        public static void TabLoadWait(this Tab tab, int maxWaitMs = 60 * 1000)
        {
            maxWaitMs = maxWaitMs/2;
            //Делаем 2 захода, для точной уверенности
            for (var i = 0; i < 2; i++)
            {
                //TODO заменить на токен
                //Когда выходим
                long maxTime = DateTime.Now.Ticks + maxWaitMs * 10000;
                //Проверям на загрузку странцы пока не кончится время или мы не получим все интересующие нас данные
                do
                {
               
                // TODO: проверка прерывания
               
                    new System.Threading.ManualResetEvent(false).WaitOne(2000);
                    if (tab.IsBusy) tab.WaitDownloading();

                    //Проверяем через js document.readyState, статус всех документов на страницы
                    bool isNotComplete = false;
                    foreach (var document in tab.AllDocuments.Documents)
                    {
                        string readyState = document.EvaluateScript("return document.readyState;");
                        if (!String.IsNullOrEmpty(readyState) && !LoadStates.Contains(readyState))
                        {
                            if (readyState != "interactive" || !document.URL.StartsWith("about:",StringComparison.Ordinal))
                                isNotComplete = true;
                        }
                    }

                    // Если у всех статус complete считаем что прошли проверку
                    if (!isNotComplete)
                        break;
                }
                while (DateTime.Now.Ticks < maxTime);
            }
        }
    }
И вызывать из c# кубика с помощью:
C#:
instance.ActiveTab.TabLoadWait();
Подскажите пожалуйста, как правильно этим кодом пользоваться?
58842
 

Phoenix78

Client
Read only
Регистрация
06.11.2018
Сообщения
11 790
Благодарностей
5 720
Баллы
113

Roman48

Client
Регистрация
28.02.2016
Сообщения
2 058
Благодарностей
745
Баллы
113

Roman48

Client
Регистрация
28.02.2016
Сообщения
2 058
Благодарностей
745
Баллы
113
Типа суда?
1593092152733.png
И не зная что это такое и для чего,, лучше не удалять, подробный скриншот покажи, пожалуйста, как правильно вставить код?
 

Roman48

Client
Регистрация
28.02.2016
Сообщения
2 058
Благодарностей
745
Баллы
113

Phoenix78

Client
Read only
Регистрация
06.11.2018
Сообщения
11 790
Благодарностей
5 720
Баллы
113
C#:
instance.ActiveTab.TabLoadWait();
И этот код использовать после клика/загрузки страницы и т.д?
ну....наверно. честно говоря даже не смотрел что там за код и что он делает.
 

zmike

Client
Регистрация
24.10.2019
Сообщения
133
Благодарностей
8
Баллы
18
[QUOTE = "Gunjubasik, post: 512245, member: 36120"]
clas
[/ QUOTE]



// wait downloading
if (instance.ActiveTab.IsBusy) instance.ActiveTab.WaitDownloading ();

Достаточно ли будет кода выше, чтобы Зенно ждал полной загрузки страницы?
 

Gunjubasik

Client
Регистрация
30.05.2019
Сообщения
3 521
Благодарностей
1 319
Баллы
113
[QUOTE = "Gunjubasik, post: 512245, member: 36120"]
clas
[/ QUOTE]



// wait downloading
if (instance.ActiveTab.IsBusy) instance.ActiveTab.WaitDownloading ();

Достаточно ли будет кода выше, чтобы Зенно ждал полной загрузки страницы?
Этого должно хватить(Снять все галочки):
61070
Если не хватит, дайте знать поищу еще метод - где то был. И укажите желательно на каком сайте у вас возникает проблема и в чем именно?
 
  • Спасибо
Реакции: IVANGOOD

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