Andrey
забирать один раз или грубо "по таймеру"
Alexey
оно как бы уже работает, но периодически начинает адски тормозить)
Andrey
до конца задачу не понимаю, но может пойти от обратного: https://stackoverflow.com/questions/54109078/puppeteer-wait-for-page-dom-updates-respond-to-new-items-that-are-added-after
Andrey
что-то вроде такого
Andrey
оно как бы уже работает, но периодически начинает адски тормозить)
может быть попробовать трейсы посмотреть что жрёт https://addyosmani.com/blog/puppeteer-recipes/
Alexander
const puppeteer = require('puppeteer'); (async() => { const browser = await puppeteer.launch(); const page = await browser.newPage(); await page.exposeFunction('onCustomEvent', text => console.log(text)); await page.goto('https://www.time.ir', {waitUntil: 'networkidle0'}); await page.evaluate(() => { $('#digitalClock').bind("DOMSubtreeModified", function(e) { window.onCustomEvent(e.currentTarget.textContent.trim()); }); }); })();
Alexey
о, спасибо! пойду пробовать!
Alexander
А вот еще The DOMSubtreeModified event has been deprecated now in favour for MutationObserver. https://github.com/puppeteer/puppeteer/issues/3719#issuecomment-506953575
Sander
Всем привет
Sander
как мокать в puppeteer? когда программа делает клик или go to? не очень представляю как тестировать, если допустим все действия puppeteer будут замоканы, то особо не потестируешь же.
Gambit501
о, спасибо! пойду пробовать!
Или попробуй на сами запросы посмотреть, может на сайте js через определенный интервал просто делает запрос на сервер к примеру к php скрипту за данными в формате json и проще их от туда парсить, ну эт как вариант
Alexey
да, такой вариант тоже рассматриваю, спасибо. Но для начала попробую через exposeFunction и MutationObserver)
Harry
Всем привет! Такой вопрос - есть сайт посылает 2 xhr запроса, второй отсылается только после получения первого. И необходимо дождаться получения именного второго запроса, чтобы взять с него данные. Как это правильно реализовать?
Alexey
привет! если понятно, по какому адресу уходит нужный запрос, то можно попробовать подписаться на событие responce: this.page.on('response', (response: Response) => { if (response.url() === 'my_url') { console.info('!!!'); } }); тогда, если я правильно понимаю механику папетира, то можно будет поймать момент, когда нужный запрос выполнился. там еще можно проверить статус response.status()
Alexey
а ты сам его закрываешь или это логика скрипта на странице такая? может ждать завершения запроса какой то таймаут и если не пришел, то тогда уже закрывать
Alexey
у тебя ведь примерно такая последовательность работы с папетиром: this.browser = await launch(launchOptions); this.page = await this.browser.newPage(); await this.page.goto(this.params.url); // тут надо поймать момент выполнения нужного xhr и данные со страницы await this.page.close(); await this.browser.close(); ? можно попробовать перед page.close() вставить ожидание таймаута, ну или лучше что-то типа await Promise.race([ waitXhr, sleep(MAX_TIMEOUT) ]); т.е. ждать xhr или таймаут - что быстрее случится
John
Никаких задержек, только выполнился xhr и дальше в путь, с delay никогда не угадаешь когда он закончится
Alexey
прикольно
Alexey
внутри, кстати, там тот же подход - подписка на 'requestfinished' + race(таймуат и запрос), но либа конечно надежнее будет, чем самому на коленке писать)
Alexey
вру, не race, а Promise.all
Harry
Есть такая штука, которая мне очень помогла... без нее очень долго боролся с ожиданием выполнения запросов https://www.npmjs.com/package/pending-xhr-puppeteer
Спасибо! Данную библиотеку в первую очередь нашел, но по ходу не разобрался, так как она отлавливала только первый xhr запрос
Pavel
https://github.com/dsheiko/puppetry
Alexander
People, а вы не знаете можно ли папетиром провести нагрузочный тест?
Alexey
вряд ли - нагрузочный тест обычно предполагает запуск чего то в N потоков на T времени в простом случае. А здесь просто управление браузером. Хотя можно конечно в цикле нажимать кнопку)
Alexander
puppeteer-cluster, puppeteer-loadtest
Alexey
ух ты, посмотрю, спасибо)
Alexander
ну это все жрет ресурсы, я вот думаю можно ли это в каком-то варианте попроще запустить
Alexander
ну оно работает как-то, но не оч
1
На сайте открывается вкладка и на ней появляется диалоговое окно. Как на этой вкладке нажать ОК в диалоговом окне? На текущей вкладке нажимаю так: page.on('dialog', async dialog => { await dialog.accept(); }); Не пойму, как на другой вкладке нажать и как эту вкладку отловить?
1
Ну типа получить другую page из браузера и на ней нажать Вот так например получается первая вкладка: const page = (await browser.pages())[0]
Спасибо, протестирую. Пришла ещё идея удалить атрибут target="_blank" перед нажатием кнопки: await page.$eval(selector, (e) => e.removeAttribute("target"));
Alex*
День добрый! А есть бесплатные прокси серверы, для потестить puppeteer c proxy-chain? Все что пробую, не работает.
Gambit501
День добрый! А есть бесплатные прокси серверы, для потестить puppeteer c proxy-chain? Все что пробую, не работает.
http://free-proxy.cz/ru/ и подобные, но там много не рабочих, хоть и пишут что проверяли недавно все ОК
Gambit501
а лучше купи, стоят не много
Alex*
Alexey
Порекомендуй, где?
вот тут например https://proxy6.net/
Alex*
вот тут например https://proxy6.net/
Да, спасибо. Я уже там.
Alex*
Остаются запущенными процессы puppeteer'а, и теряем память.
Alex*
Alex*
Вроде закрываю страницы page.close(). Но процессы остаются. Куда копать?
Gambit501
?
Alex*
а как же await browser.close();
Это тоже есть. Вроде нашел причину. Это происходило в ситуации, когда сайт отдает 200 но контент не отдает. Стал делать запрос до puppeteer.launch
Sasha
Доброго дня.
Sasha
Подскажите как сделать поиск по css при том что класс динамический но имеет статический элемент
Sasha
класс типа .side-picture-**** где *** это цифры
Gambit501
Подскажите как сделать поиск по css при том что класс динамический но имеет статический элемент
Посмотри вот это, думаю подойдет https://developer.mozilla.org/ru/docs/Web/CSS/Attribute_selectors
Sasha
Да вот что то не могу понять как мне этот класс поймать. Тут элемент iframe и я ищу его для клика на элемент. Везде он в разных местах но имеет 1 и тот же класс
Sasha
Но концавка его рандомно меняется
Andrey
Перебери все айфреймы и ручками посмотри класс
Sander
у меня почему-то из-за puppeteer.launch({ args['--single-process'] }), падает программа, onError: caught (1)! Error: Navigation failed because browser has disconnected! Error: Protocol error: Connection closed. Most likely the page has been closed. как бы везде тоже самое использую, а падает оно именно когда делаю обычный goto: await page.goto(uploadUrl, { waitUntil: 'networkidle0', })
Sander
вопрос в puppeteer - как-то можно сделать так чтоб, он сразу вставил текст в texarea copy-paste-ом, просто когда он по сивольно пишет быстро, это выглядит не очень, может как-то сразу текст можно вставить, словно copy-paste?
Sander
await puppeteerPage.keyboard.down('Control') await puppeteerPage.keyboard.press('V') await puppeteerPage.keyboard.up('Control')
Sander
ну такое себе
Sander
надежней уж чтоб он просто напечатал текст, мне надо то что выполняет свои действия надежней
Sander
мне кажется что проблемы могут всякие еще возникнуть, с подобной логикой, которую я выше написал, лучше использовать тот вариант что проще и надежней
Sander
у меня просто slowMo и мне интересно, можно ли в определенном месте сделать так чтоб он печатал быстрей? а то скорость не меняется
Sander
я пытался, но typescript-у почему-то не нравитьяс этот вариант
Sander
момент
Sander
await page.$eval( descriptionSelector, (element, value) => (element.value = value), postDescription, )
Sander
Назар
а пишет что?
Назар
вроде работать должно, только напиши что element это any
Sander
Sander
Sander
я никогда eval не использовал, в чем разница между другими способами?
Назар
а вторая то как я понял линтер не дает менять переменную из параметра. Это нужно скипнуть через комент
Sander
я обыбчно делал через await page.evaluate()
Sander
а вторая то как я понял линтер не дает менять переменную из параметра. Это нужно скипнуть через комент
да так можно, но я все токи думал что можно нормально написать без комментов и any ((
Назар
eval запустит код в браузере. По сути тоже самое, вроде evaluate просто запустит функцию без query элемента, нужно будет еще квери сделать
Назар
да так можно, но я все токи думал что можно нормально написать без комментов и any ((
без any можно. Нужно сделать привидения типа. ((element as HTMLInputElement).value = value)