我使用以下代码提交表单,我希望Puppeteer在表单提交后等待页面加载。
await page.click("button[type=submit]");
//how to wait until the new page loads before taking screenshot?
// i don't want this:
// await page.waitFor(1*1000); //← unwanted workaround
await page.screenshot({path: 'example.png'});
如何使用puppeteer等待页面加载?
答案 0 :(得分:31)
您可以异步等待导航,以避免在重定向上获得null
,
await Promise.all([
page.click("button[type=submit]"),
page.waitForNavigation({ waitUntil: 'networkidle0' }),
]);
如果page.click已触发导航,这将对您有所帮助。
答案 1 :(得分:25)
await page.waitForNavigation();
答案 2 :(得分:12)
根据Official Documentation,您应该使用:
page.waitForNavigation(选项)
options
<Object>导航参数,可能具有以下属性:
timeout
<number>最长导航时间(以毫秒为单位),默认为30秒,请传递0
以禁用超时。可以使用page.setDefaultNavigationTimeout(timeout)方法来更改默认值。waitUntil
<string | Array <string >>当考虑导航成功时,默认为load
。给定事件字符串数组,所有事件触发后,导航被认为是成功的。事件可以是:
load
-考虑触发load
事件时导航完成。domcontentloaded
-考虑触发DOMContentLoaded
事件时导航完成。networkidle0
-当至少500
毫秒内网络连接不超过0个时,请考虑完成导航。networkidle2
-至少有500
毫秒的网络连接不超过2个时,请考虑完成导航。- 返回:<Promise <[?Response] >>承诺,它解决了主要资源的响应。如果是多次重定向,导航将以最后一次重定向的响应来解决。如果使用History API导航到其他锚点或导航,导航将以
null
解析。
您可以使用page.waitForNavigation()
等待页面导航:
await page.waitForNavigation();
但是,由于page.waitForNavigation()
是page.mainFrame().waitForNavigation()
的快捷方式,因此我们可以使用以下内容来改善性能:
await page._frameManager._mainFrame.waitForNavigation();
答案 3 :(得分:0)
await Promise.all([
page.click(selectors.submit),
page.waitForNavigation({ waitUntil: 'networkidle0' }),
]);
这将是第一个使用的优先级,因为它等待所有网络完成,并假定在500毫秒内网络呼叫不超过0个时完成。
您也可以使用
await page.waitForNavigation({ waitUntil: 'Load' }}
否则,您可以使用
await page.waitForResponse(response => response.ok())
此功能也可以在各个地方使用,因为它仅允许在所有呼叫都成功时(即,所有响应状态都正常时,即(200-299))进一步进行操作
答案 4 :(得分:0)
我知道回答这个问题有点晚了。对于在执行 waitForNavigation 时遇到异常的人可能会有所帮助。
(节点:14531)UnhandledPromiseRejectionWarning:TimeoutError: 超过导航超时:超过30000ms 然后在Promise.then(/home/user/nodejs/node_modules/puppeteer/lib/LifecycleWatcher.js:142:21) 在-ASYNC- 在帧。 (/家庭/用户/nodejs/node_modules/puppeteer/lib/helper.js:111:15) 在Page.waitForNavigation(/home/user/nodejs/node_modules/puppeteer/lib/Page.js:649:49) 在Page。 (/家庭/用户/nodejs/node_modules/puppeteer/lib/helper.js:112:23) 在/home/user/nodejs/user/puppeteer/example7.js:14:12
对我有用的正确代码如下。
await page.click('button[id=start]', {waitUntil: 'domcontentloaded'});
类似地,如果您要转到新页面,则代码应类似于
await page.goto('here goes url', {waitUntil: 'domcontentloaded'});
答案 5 :(得分:0)
有时甚至使用await page.waitForNavigation()
仍会产生Error: Execution context was destroyed, most likely because of a navigation.
就我而言,这是因为页面被多次重定向。 API表示默认的waitUntil
选项是Load
,这需要我等待每次重定向的导航(3次)。在我的情况下,仅将page.waitForNavigation
的单个实例与waitUntil
选项networkidle2
一起使用会很好:
await button.click();
await page.waitForNavigation({waitUntil: 'networkidle2'});
最后,API建议使用Promise.All
来防止出现竞争情况。 我不需要这个,但是为了完整性而提供:
await Promise.all([button.click(), page.waitForNavigation({waitUntil:'networkidle2'})])
如果所有其他方法均失败,则可以按照page.waitForSelector
上的建议使用Puppeteer github issue-在我的情况下,可以使用page.waitForXPath()
答案 6 :(得分:0)
我建议将page.to包装在包装器中,然后等待所有内容加载
这是我的包装纸
loadUrl: async function (page, url) {
try {
await page.goto(url, {
timeout: 20000,
waitUntil: ['load', 'domcontentloaded', 'networkidle0', 'networkidle2']
})
} catch (error) {
throw new Error("url " + url + " url not loaded -> " + error)
}
}
现在您可以将其与
一起使用await loadUrl(page, "https://www.google.com")
答案 7 :(得分:0)
我遇到了一个场景,其中有经典的POST-303-GET并涉及input[type=submit]
。在这种情况下,按钮的click
似乎要等到关联表单的提交和重定向之后才能解析,因此解决方案是删除waitForNavigation
,因为它是在重定向并执行之后执行的。因此就超时了。
答案 8 :(得分:0)
这对我有用:
await Promise.all([
page.goto(URL),
page.waitForNavigation({ waitUntil: 'networkidle0' }),
]);
console.log('page loaded')
由于某种原因,我无法单击按钮(处理了一个事件,未采用表格形式)
<button onclick="someFunction();" class="button button2">Submit</button>
问题在于该页面是在服务器端呈现的。因此,每当我等待输入字段await page.waitForSelector('button.button2')
解决方案是将page.goto(URL)
中的page.waitForNavigation({ waitUntil: 'networkidle0' })
和Promise
绑定
await Promise.all([
page.goto(URL),
page.waitForNavigation({ waitUntil: 'networkidle0' }),
]);
console.log('page loaded')
await page.waitForSelector('button.button2')
console.log('button is here');
答案 9 :(得分:0)
如果提交表单会打开其他页面,那么您可能只想等待该页面中的选择器。我经常在使用 page.waitForNavigation()
时遇到问题,因为它的选项并不能真正确保我们有效地导航到另一个页面。
// login page
page.click("#login");
// homepage, after login
page.waitForSelector("#home", {visible: true}); // page.waitForXpath()
当然,您可以增加选择器的等待时间。