Сценарий не должен проиграть человеку, у которого есть только ручное управление, такое как кнопка F5.
Это происходит потому, что иногда правила, которым следует кукловод, намного строже, чем то, что мы считаем «полностью загруженная веб-страница». Даже если вы, как человек, можете решить, находится ли желаемый элемент уже в DOM (потому что вы видите, что элемент есть) или его нет (потому что вы его не видите). Например: вы увидите, что вашей кнопки нет, даже если фоновое изображение все еще загружается в фоновом режиме, или веб-шрифты все еще не загружены, а у вас есть резервные шрифты, но кукловод ждет определенных c событий в фоновом режиме, чтобы получить разрешение либо на go блоку catch (тайм-аут), либо на захват желаемого элемента (waitForSelector успешно). Это действительно может зависеть от сайта, который вы посещаете, но вы можете ускорить процесс распознавания желаемого элемента.
Я даю несколько примеров и идеи, как этого добиться.
Способы ускорения распознавания желаемого элемента
1.) Если вам не нужны все сетевые подключения для вашей задачи, вы можете ускорить загрузку страницы, заменив waitUntil: 'networkidle2'
на waitUntil: 'domcontentloaded'
как это событие обычно происходит раньше и запускается, когда #ourButton
уже присутствует в DOM.
Возможные варианты page.goto
/ page.reload
:
load
- считайте, что навигация завершена при срабатывании события load
. domcontentloaded
- считайте, что навигация завершена, когда запускается событие DOMContentLoaded
. networkidle0
- учтите завершение навигации при наличии не более 0 сетевых подключений в течение не менее 500
мс. networkidle2
- считайте, что навигация завершена, когда имеется не более 2 сетевых подключений для не менее 500
ms.
Вы выигрываете, потому что networkidle2
слишком строгий. Вам может понадобиться эта опция (например, вы посещаете одностраничное приложение или позже вам потребуются данные из стороннего сетевого подключения, например файлы cookie), но если это не обязательно, вы получите лучшую производительность с domcontentloaded
.
2.) Вместо постоянного перехода к одному и тому же URL-адресу вы можете использовать метод page.reload
в al oop, например:
await page.goto(url, { waitUntil: 'domcontentloaded' })
let selectorExists = await page.$('#ourButton')
while (selectorExists === null) {
await page.reload({ waitUntil: 'domcontentloaded' })
console.log('reload')
selectorExists = await page.$('#ourButton')
}
await page.click('#ourButton')
// code goes on...
Его главное преимущество в том, что вы могут сократить и упростить вашу функцию pageRefresher
. Но я также испытал лучшую производительность (хотя я не проводил тестов, но я чувствовал, что это намного быстрее, чем повторное открытие страницы).
3.) Если вам не нужны все типы ресурсов для вашей задачи, вы также можете ускорить загрузку страницы, отключив изображения или css с помощью следующего скрипта:
await page.setRequestInterception(true)
page.on('request', (request) => {
if (request.resourceType() === 'image') request.abort()
else request.continue()
})
[источник]
Список resourceType - с.