简体   繁体   中英

puppeteer: wait N seconds before continuing to the next line

In puppeteer I would like to wait a defined time before going to the next line of code.

I've tried to put a setTimeout in an evaluate function but it seems to be simply ignored

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

This code don't wait and just write before waiting and after waiting

Do you know how to do this?

You can use a little promise function,

function delay(time) {
   return new Promise(function(resolve) { 
       setTimeout(resolve, time)
   });
}

Then, call it whenever you want a delay.

console.log('before waiting');
await delay(4000);
console.log('after waiting');

If you must use puppeteer use the builtin waitForTimeout function.

await page.waitForTimeout(4000)

If you still want to use page.evaluate, resolve it after 4 seconds. You are not resolving anything.

await page.evaluate(async() => {
    await new Promise(function(resolve) { 
           setTimeout(resolve, 1000)
    });
});

But I guess you can simply use the first two examples.

I've been using:

await page.waitForTimeout(3000);

Where 3000 is Milliseconds And that seems to be working for me.

You can use one of the following options to wait for one second :

await page.waitFor(1000);
await frame.waitFor(1000);
await new Promise(r => setTimeout(r, 1000));

Alternatively, there are many Puppeteer functions that include a built-in delay option, which may come in handy for waiting between certain events:

// 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});

page.waitFor has now been deprecated.

page.waitForTimeout is now advised to pause script execution for the given number of milliseconds before continuing:

await page.waitForTimeout(1000)

Try this function.

function sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}

to use it

  async function demo() {
    console.log('Waiting...');
    await sleep(3000);
    console.log('ok');
  }

  demo();
await new Promise(_func=> setTimeout(_func, 5000));

Other answers have shown how to sleep, but now that page.waitForTimeout is finally deprecated , I figure I'd add the answer I've wanted to add for awhile:

Don't sleep, It causes a race condition that disrupts the event-driven nature of Puppeteer. introducing unnecessary brittleness: There's almost always a better predicate to wait on:

  • Are you waiting for a selector to appear? Try waitForSelector .
  • Are you waiting for an XPath to appear? Try waitForXPath .
  • Are you waiting for a navigation? Try waitForNavigation .
  • Are you waiting for a network response? Try waitForNetworkIdle or waitForResponse .
  • Are you waiting for a popup? Try promisifying .on("dialog", ...
  • Are you waiting for some arbitrary predicate, like a minimum number of child elements to appear? Try waitForFunction .
  • Something else? Run an evaluate block and add your own code to wait for a DOM mutation or poll with setInterval or requestAnimationFrame and effectively reimplement waitForFunction as fits your needs.

waitForFunction in particular is underused but it adds a huge amount of reliability and precision that waitForTimeout doesn't.

If all else fails and you have to block the script, you can delay, but I've written hundreds of Puppeteer scripts and have never had to use any sleep variant, so I'm pretty convinced it's basically unnecessary.

See my blog post on Puppeteer Antipatterns for more analysis of why you should avoid sleeping in any form except as an absolute last resort.

Your syntax is incomplete.
Try this...

await page.evaluate(async() => {
    setTimeout(function(){
        console.log('waiting');
    }, 4000)
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM