【发布时间】:2019-12-28 22:52:42
【问题描述】:
第一次尝试puppeteer,真是太棒了。 单击按钮后,我需要等待页面获取和呈现新数据。这不会导致导航(网址相同)因此以下代码不起作用(它给出超时异常):
await Promise.all([
myButton.click()
page.waitForNavigation()
])
等待页面在点击时获取/呈现异步数据的正确方法是什么?
【问题讨论】:
标签: javascript puppeteer
第一次尝试puppeteer,真是太棒了。 单击按钮后,我需要等待页面获取和呈现新数据。这不会导致导航(网址相同)因此以下代码不起作用(它给出超时异常):
await Promise.all([
myButton.click()
page.waitForNavigation()
])
等待页面在点击时获取/呈现异步数据的正确方法是什么?
【问题讨论】:
标签: javascript puppeteer
假设 DOM 以某种方式发生变化,您可以等待特定元素或选择器。
可能会出现图像。
await myButton.click();
await page.waitForSelector('img.success');
也许某些具有 ID 属性的元素被插入到 DOM 中。
await myButton.click();
await page.waitForSelector('#newElementThatAppeared');
如果您不熟悉 DOM 选择器,可以阅读 here 和 here。它们功能强大且易于使用。
更新 - 自定义等待谓词。
如果我们总是知道长度...
await myButton.click();
await page.waitFor(() => document.querySelectorAll('ul.specialList li').length > 5);
如果我们知道长度会增加
const listSize = await page.evaluate(() => document.querySelectorAll('ul.specialList li').length);
await myButton.click();
await page.waitFor(() => document.querySelectorAll('ul.specialList li').length > listSize);
【讨论】:
嗯,有点破解,但目前没有找到更好的解决方案。 基本上我是在点击按钮之前和之后比较特定 li 元素的数量,以验证何时加载了新数据。
const wait = time => new Promise(resolve => setTimeout(resolve, time))
let data = await page.evaluate(_ => document.querySelectorAll("li.className").length)
let isDataLoaded = false
await page.click("#myButton")
while(!isDataLoaded) {
if (data.length !== await.page.evaluate(_ => document.querySelectorAll("li.className").length)) {
isDataLoaded = true
}
await wait(100)
}
// new data should be loaded and rendered now in the page
// [...]
【讨论】:
waitFor吗?
await page.waitFor(() => document.querySelectorAll('li.className').length != listSize);
listSize。你称它为data。是这个问题吗?
首先await Promise.all某种并发,如果你需要点击然后等待用
await page.click('#selector');
const finalResponse = await page.waitForResponse(response => response.url() === 'https://example.com' && response.status() === 200);
return finalResponse.ok();
并成为noted:
这会在页面导航到新 URL 或重新加载时解决。
【讨论】: