puppeteer:在继续下一行之前等待N秒

Viv*_*ipo 30 javascript chromium browser-testing node.js puppeteer

puppeteer中我想在进入下一行代码之前等待一段确定的时间.

我试图setTimeout在一个评估函数中,但它似乎被忽略了

console.log('before waiting');
await page.evaluate(async() => {
  setTimeout(function(){
      console.log('waiting');
  }, 4000)
});
console.log('after waiting');
Run Code Online (Sandbox Code Playgroud)

此代码不等待,只是在等待之前等待之后写入

你知道怎么做吗?

Md.*_*her 67

你可以使用一点承诺功能,

function delay(time) {
   return new Promise(function(resolve) { 
       setTimeout(resolve, time)
   });
}
Run Code Online (Sandbox Code Playgroud)

然后,只要你想要延迟,就打电话给它.

console.log('before waiting');
await delay(4000);
console.log('after waiting');
Run Code Online (Sandbox Code Playgroud)

如果你必须使用puppeteer使用内置的waitFor函数.

await page.waitFor(4000)
Run Code Online (Sandbox Code Playgroud)

如果您仍想使用page.evaluate,请在4​​秒后解决.你没有解决任何问题.

await page.evaluate(async() => {
    await new Promise(function(resolve) { 
           setTimeout(resolve, 1000)
    });
});
Run Code Online (Sandbox Code Playgroud)

但我想你可以简单地使用前两个例子.

  • 我很确定延迟功能和page.evaluate是不同的示例。 (2认同)
  • `waitFor` 已弃用,请使用 `waitForTimeout` 代替。 (2认同)

Mat*_*sGB 17

page.waitFor现在已被弃用。

现在建议page.waitForTimeout在继续之前暂停脚本执行给定的毫秒数:

await page.waitForTimeout(1000)
Run Code Online (Sandbox Code Playgroud)


Gra*_*ler 11

您可以使用以下选项之一等待一秒钟:

await page.waitFor(1000);
await frame.waitFor(1000);
await new Promise(r => setTimeout(r, 1000));
Run Code Online (Sandbox Code Playgroud)

或者,有许多Puppeteer函数包含一个内置delay选项,在某些事件之间等待可能会派上用场:

// Click Delay
// Time to wait between mousedown and mouseup in milliseconds. Defaults to 0.

await page.click('#example', {delay: 1000});
await frame.click('#example', {delay: 1000});
await elementHandle.click({delay: 1000});
await page.mouse.click(0, 0, {delay: 1000});

// Type Delay
// Time to wait between key presses in milliseconds. Defaults to 0.

await page.type('#example', 'Hello, world!', {delay: 1000});
await frame.type('#example', 'Hello, world!', {delay: 1000});
await elementHandle.type('Hello, world!', {delay: 1000});
await page.keyboard.type('Hello, world!', {delay: 1000});

// Press Delay
// Time to wait between keydown and keyup in milliseconds. Defaults to 0.

await elementHandle.press('Backspace', {delay: 1000});
await page.keyboard.press('Backspace', {delay: 1000});
Run Code Online (Sandbox Code Playgroud)

  • waitFor 已弃用并将被删除。新功能是 waitForTimeout https://github.com/puppeteer/puppeteer/issues/6214 (4认同)
  • waitForTimeout 也已被弃用 (2认同)

ggo*_*len 10

其他答案已经展示了如何睡眠,但现在它最终在 16.1.1 中被弃用page.waitForTimeout,并在 22.0.0 中被删除,我想我会添加我想添加一段时间的答案:

别睡!它会导致竞争条件,从而破坏 Puppeteer 的事件驱动性质,从而引入不必要的脆弱性。几乎总是有更好的谓词等待,无论是显式的还是使用Locator API:

  • 您是否正在等待 CSS 选择器、aria 标签、文本或 XPath 的出现?尝试waitForSelector(可选地使用适当的内置选择器)。
  • 你在等导航吗?尝试waitForNavigation或调整waitUntil上的选项goto
  • 您是否在等待网络事件或状态?尝试一下waitForRequestwaitForResponse或者waitForNetworkIdle
  • 您在等待弹出窗口吗?尝试许诺page.on("dialog", ...
  • 您是否正在等待一些任意谓词,例如出现最小数量的子元素?尝试waitForFunction
  • 还有别的事吗?运行一个evaluate块并添加您自己的代码以等待 DOM 突变或使用setIntervalor进行轮询requestAnimationFrame,并waitForFunction根据您的需求有效地重新实现。

waitForFunction特别是未得到充分利用,但它增加了大量的可靠性和精度,而这是waitForTimeout没有的。

如果所有其他方法都失败并且您必须阻止脚本,您可以延迟,但我已经编写了数百个 Puppeteer 脚本并且从未使用过任何睡眠变体,所以我非常确信这基本上是不必要的。

请参阅我关于 Puppeteer Antipatterns 的博客文章,了解为什么应该避免以任何形式睡觉(除非作为绝对的最后手段)的更多分析。

另请参阅的 Playwright 文档waitForTimeout,它与 Puppeteer 方法本质上相同:

灰心

永远不要在生产中等待超时。等待时间的测试本质上是不稳定的。使用自动等待的定位器操作和 Web 断言。

对上述内容的一个警告:睡眠对于开发脚本时的临时调试很有用。


Huc*_*nan 7

我一直在使用:

await page.waitFor(3000);
Run Code Online (Sandbox Code Playgroud)

3000是毫秒,这似乎对我有用。

  • `page.waitForTimeout()` 现已过时。替换为 `new Promise(r => setTimeout(r, 毫秒));` (6认同)
  • waitfor() 已被废弃。使用 page.waitForTimeout(1000) 代替 (3认同)