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

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

The_vAe

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

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

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

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


Если Вы так уже делали и считаете, что вариантов больше нет - присылайте конкретный пример, будем смотреть.
 
Когда какие-то данные подгружаются на страничке - сайт отправляет какие-то запросы.
А в Зеннопостере есть такая штука, которая позволяет отслеживать запросы.
И вот, уже исходя из этого можно сообразить следующую логику - берем все запросы в список.
Дальше - ждём например 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;
 
Спасибо, большое. Но можно более детально, как отслеживать запросы и как обращаться с кодом, предложенным вами? Так как я не силен в кодировке.

Когда какие-то данные подгружаются на страничке - сайт отправляет какие-то запросы.
А в Зеннопостере есть такая штука, которая позволяет отслеживать запросы.
И вот, уже исходя из этого можно сообразить следующую логику - берем все запросы в список.
Дальше - ждём например 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;
 
Спасибо, большое. Но можно более детально, как отслеживать запросы и как обращаться с кодом, предложенным вами? Так как я не силен в кодировке.
Добавить в кубик свой С#.
Результат сохранять в переменную.
Если вернёт True - значит сайт больше ничего не грузит.
Если вернет False - значит сайт всё ещё шлёт какие-то запросы.
Паузы, естественно нужно подправить под свой случай (мне обычно выставленных в коде хватает, но, бывает приходится либо у уменьшать или увеличивать).
 
А с этим помочь можете?


Добавить в кубик свой С#.
Результат сохранять в переменную.
Если вернёт True - значит сайт больше ничего не грузит.
Если вернет False - значит сайт всё ещё шлёт какие-то запросы.
Паузы, естественно нужно подправить под свой случай (мне обычно выставленных в коде хватает, но, бывает приходится либо у уменьшать или увеличивать).
 
Где-то 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();
 
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();
 
у меня тоже все время пишет, что все ОК. Хоть первый, хоть второй вариант кода
 
у меня тоже все время пишет, что все ОК. Хоть первый, хоть второй вариант кода
Периодически работает этот:
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;
Но только иногда до конца справляется.))) Завершает то позже нужного, то раньше.)))
 
Но только иногда до конца справляется.))) Завершает то позже нужного, то раньше.)))
Данный код считает запросы - если есть хотя бы 1 запрос - за последних 3-5 секунд - ожидает.
И так повторяет 20 раз.
Но, если на сайте постоянно что-то грузится - тогда он выйдет по успеху - проверяйте нужные данные на страничке - если их нет - возвращайтесь дальше на данный кубик.
Также совсем не объязательно дожидаться всех запросов - возможно есть смысл увеличить значение и прекращать, if(traffic.Count > 3).


Данный код не проверяет выполнение яваскрипта - и если какие-то данные получаются - то возможно есть смысл дать дополнительно несколько секунд ожидания на отработку запроса.
Или... Изучать более тщательно сайт, чтобы понять в чём именно на этом сайте проблема.
 
  • Спасибо
Реакции: The_vAe
Объединил оба решения - вроде бы стало стабильнее ловить
 
Не смотря на оффтоп, может есть еще какие то действенные решения, как ловить исполнение Javascript? Трафик в этот момент не передается, а может висеть какой то индикатор проегресса, как ожидание отдачи данных.
 
Подскажите, пожалуйста, вот я поймал 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();
 
Где-то 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
 
Типа суда?
1593092152733.png
И не зная что это такое и для чего,, лучше не удалять, подробный скриншот покажи, пожалуйста, как правильно вставить код?
 
C#:
Развернуть Свернуть Копировать
instance.ActiveTab.TabLoadWait();
И этот код использовать после клика/загрузки страницы и т.д?
ну....наверно. честно говоря даже не смотрел что там за код и что он делает.
 
[QUOTE = "Gunjubasik, post: 512245, member: 36120"]
clas
[/ QUOTE]



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

Достаточно ли будет кода выше, чтобы Зенно ждал полной загрузки страницы?
 
[QUOTE = "Gunjubasik, post: 512245, member: 36120"]
clas
[/ QUOTE]



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

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

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