网页上有一个按钮,操纵up的人必须尽快单击该按钮。此按钮并不总是可见的,并且同时对每个人都可见。因此,我必须不断刷新以发现该按钮变得可见。我为此编写了以下脚本:
const browser = await puppeteer.launch({
headless: true,
args: ['--no-sandbox']
});
const page = await browser.newPage()
await page.setViewport({ width: 1920, height: 1080})
//I am calling my pageRefresher method here
async function pageRefresher(page,browser, url) {
try {
await page.goto(url, {waitUntil: 'networkidle2'})
try {
await page.waitForSelector('#ourButton', {timeout: 10});
await page.click('#ourButton')
console.log(`clicked!`)
await browser.close()
} catch (error) {
console.log('catch2 ' + counter + ' ' + error)
counter += 1
await pageRefresher(page, browser, url)
}
}catch (error) {
console.log('catch3' + error)
await browser.close();
}
}
如您所见,我的方法是递归的。它会转到该页面并寻找该按钮。如果没有按钮,则它将再次调用自身以重做相同的作业,直到找到并单击该按钮为止。
实际上,它现在运行良好。但这很慢。我正在运行此脚本,与此同时,我正在桌面chrome上打开同一页面,并且开始手动刷新该页面。而且我总是赢,我总是在操纵up之前单击该按钮。
我如何加快此过程?脚本不应该输给只有F5按钮之类的手动控件的人。
答案 0 :(得分:4)
脚本不应输给只有F5按钮等手动控件的人。
之所以会发生这种情况,是因为有时伪造者遵循的规则比我们认为的“完全加载的网页”要严格得多。即使您作为一个人也可以决定所需的元素是否已经在DOM中(因为您看到该元素在其中)或该元素不在其中(因为您没有看到它)。例如:即使背景图片仍在后台加载,或者仍然没有加载Web字体并且您具有后备字体,您仍会看到按钮不存在,但是puppeteer在后台等待特定事件以获得许可要么转到catch块(超时),要么获取所需的元素(waitForSelector成功)。它确实取决于您所访问的站点,但是您可以加快识别所需元素的过程。
我提供一些示例和想法,您可以如何实现这一目标。
1。)如果您不需要所有网络连接来完成任务,则可以通过将waitUntil: 'networkidle2'
替换为waitUntil: 'domcontentloaded'
来加快页面加载速度,因为该事件通常发生在更早的时刻,并且会在{{ 1}}将已经存在于DOM中。
#ourButton
/ page.goto
的可能选项:
page.reload
-考虑触发load
事件时导航完成。load
-考虑触发domcontentloaded
事件时导航完成。DOMContentLoaded
-至少有networkidle0
毫秒的网络连接不超过0个时,请考虑完成导航。500
-至少有networkidle2
毫秒的网络连接不超过2个时,请考虑完成导航。您因为500
太严格而赢得了脚本。您可能需要此选项(例如,您正在访问单页应用程序,或者稍后您将需要来自第三方网络连接的数据(例如Cookie)),但是如果不是强制性的,则使用networkidle2
会获得更好的性能。 / p>
2。)您可以循环使用page.reload
方法,而不是不断导航到相同的url,例如:
domcontentloaded
它的主要好处是您可以缩短和简化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...
函数。但是我的表现也更好(但是我没有进行基准测试,但是感觉比重新打开页面要快得多。)
3。)如果不需要执行任务的每种资源类型,还可以通过使用以下脚本禁用图像或CSS来加快页面加载速度:
pageRefresher
答案 1 :(得分:2)
尝试不等待goto:
page.goto(url) // no await because it doesn't have to resolve fully
await page.waitForSelector('#ourButton') // await this because we need it to be there
有些人喜欢Promise.race,但是这种方式更简单