Puppeteer流程逻辑,检查是否发生了导航(与等待相对)

4

寻求一些反馈。在 Puppeteer 中,我想检查是否发生了导航,如果发生了,就做某件事情;否则,做另外一件事情(例如,再试一次)。我想到了两种方法:

if (await page.url() != finalURL) {
    let t = 0;  
    busy: while(t > 400) {
        try {
            await Promise.all([
                await page.click('#tryAgainLink'),
                await page.waitForNavigation(),
            ]);
            break busy;
        } catch(err) {
            // navigation didn't happen
            t++;
            await page.waitForTimeout(1500);
        }
    }
}

然而,我了解到在流程逻辑中不理想的是使用try/catch。我的替代方案如下:

let t = 0;
busy: while(await page.url() != finalURL) {
    await page.click('#tryAgainLink');
    await page.waitForTimeout(1500);
    t++;
    if(t > 400) {
        break busy;
    }
}

我在想是否应该在其中加入waitForNavigation,但如果没有这个命令,我就得捕获抛出的错误。我是想测试一下,但我不确定当导航正在进行时,那个while循环中的await page.url()是否会触发多次,或者是否会破坏页面上下文。
有比上面两种方法更好的方法吗?第一种方法确实可行,我倾向于保留它。谢谢。

1
不确定为什么你在第一个例子中使用了 Promise.all。内部的 await 使其无效。 - Ouroborus
1
@Ouroborus 内部的 await 应该被省略,这是因为一遍又一遍地输入 await page.* 的习惯。它们都在 Promise.all 中的原因是来自 Puppeteer 文档的解释:"如果 click() 触发了一个导航事件,并且有一个单独的 page.waitForNavigation() promise 需要被解决,你可能会遇到竞争条件,从而产生意外的结果。" - Davis
相关问题:使用Puppeteer检测导航 - ggorlen
3个回答

1
我使用这种方法:

async function isNavigation() {
  try {
    await page.evaluate(() => console.log('any code'))
    return false
  } catch (ex) {
    // check error, should be:
    // "Execution context was destroyed, most likely because of a navigation"
    return true
  }

}


1
您应该能够做类似以下的事情:
await page.waitForFunction((finalUrl) => {
  return document.location === finalUrl
}, {}, finalUrl).catch(retry)

但可能更简单的方法是:
await page.waitForResponse(finalUrl).catch(retry)

0

可能是这样的:

if (page.url() !== finalURL) { // await is not needed here
    let t = 0;
    busy: while(t < 400) { // was '> 400' a typo?
        const [_, navigation] = await Promise.allSettled([
            page.click('#tryAgainLink'),
            page.waitForNavigation(),
        ]);

        if (navigation.status === 'fulfilled') break busy;

        t++;
        await page.waitForTimeout(1500);
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接