puppeteer wait for page update after button click (no navigation)

北城余情 提交于 2020-03-03 06:49:38

问题


Trying puppeteer for the first time and it is amazing. I need to wait for a page to fetch and render new data after a button click. This does not cause a navigation (the url is the same) so the following code does not work (it gives timeout exception):

await Promise.all([
    myButton.click()
    page.waitForNavigation()
])

What's the correct way to wait for the page to fetch/render async data on click?


回答1:


Assuming the DOM changes in some way, you can wait for a specific element or selector.

Maybe an image appears.

await myButton.click();
await page.waitForSelector('img.success');

Maybe some element with an ID attribute is inserted into the DOM.

await myButton.click();
await page.waitForSelector('#newElementThatAppeared');

If you're unfamiliar with DOM selectors, you can read up here and here. They're powerful and easy to use.

Update - Custom wait predicate.

If we always know the length...

await myButton.click();
await page.waitFor(() => document.querySelectorAll('ul.specialList li').length > 5);

If we know the length will increase

const listSize = await page.evaluate(() => document.querySelectorAll('ul.specialList li').length);
await myButton.click();
await page.waitFor(() => document.querySelectorAll('ul.specialList li').length > listSize);



回答2:


First of all await Promise.all some kind of concurrency and if you need click and then wait split this with

await page.click('#selector');
const finalResponse = await page.waitForResponse(response => response.url() === 'https://example.com' && response.status() === 200);
return finalResponse.ok();

And be noted:

This resolves when the page navigates to a new URL or reloads.




回答3:


Well, kind of an hack but didn't find any better solution for now. Basically I am comparing the number of specific li elements before and after the button click to verify when new data has been loaded.

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
// [...]


来源:https://stackoverflow.com/questions/57629246/puppeteer-wait-for-page-update-after-button-click-no-navigation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!