令人难以置信的奇怪的木偶行为

时间:2018-05-04 00:10:09

标签: node.js asynchronous puppeteer

我使用此代码:

// <-- add event on top of file
process.on("unhandledRejection", (reason, p) => {
        console.error("Unhandled Rejection at: Promise", p, "reason:", reason);
        // browser.close(); // <-- no need to close the browser here
});

const puppeteer = require('puppeteer');
async function getPic() {
    try{ // <-- wrap the whole block in try catch
      const browser = await puppeteer.launch(/*{headless: false}*/);
      const page = await browser.newPage();
      await page.setViewport({width: 1000, height: 500}); // <-- add await here so it sets viewport after it creates the page


      //await page.goto('https://www.google.com');  //Old way of doing. It doesn't work for some reason...

      page.goto('https://www.google.com/').catch(error => console.log("error on page.goto()", error));


      // wait for either of events to trigger
      await Promise.race([
        page.waitForNavigation({waitUntil: 'domcontentloaded'}),
        page.waitForNavigation({waitUntil: 'load'})
      ]);


      await page.screenshot({path: 'pic.png'});
      await browser.close(); // <-- close browser after everything is done
    } catch (error) {
      console.log(error);
    }
}

getPic();

然后程序挂起。 30秒后,我收到此错误:

error on page.goto() Error: Navigation T imeout Exceeded: 30000ms exceeded at Promise.then (C:\...\pupet test\node_modules\puppeteer\lib\NavigatorWatcher.js:71:21) at <anonymous>

但我也得到了我要求的照片!

1.那么page.goto()是如何失败的,但它仍然得到了图片,这意味着page.goto()实际上工作了!? 2.我能做些什么来缓解这个奇怪的错误?

1 个答案:

答案 0 :(得分:0)

程序挂起是因为你没有async-await或promises就调用了goto,然后你把它放在了waitForNavigation的竞争中,这让浏览器感到困惑,因为所有三行代码在后面大部分都做同样的事情。它试图导航并等待它。

对promises使用async await。不要以同步方式调用异步方法。无论如何,这都是你必须在示例中使用它的方式。

await page.goto('https://www.google.com');

如果你想等到页面加载,那么goto函数也会覆盖它。您不需要在waitForNavigation之后使用goto

await page.goto('https://www.google.com', {waitUntil: 'load'}); 

domcontentloaded属性还有networkidle2networkidle0waitUntil。您可以在文档中阅读有关它的更多信息,并提供完整的解释。

屏幕截图工作正常的原因是因为它异步执行,但之后您正在等待导航。

这是没有太多复杂性和承诺竞争的代码。

try{ // <-- wrap the whole block in try catch
      const browser = await puppeteer.launch(/*{headless: false}*/);
      const page = await browser.newPage();
      await page.setViewport({width: 1000, height: 500}); // <-- add await here so it sets viewport after it creates the page
      await page.goto('https://www.google.com/', {waitUntil: 'load'})
      await page.screenshot({path: 'pic.png'});
      await browser.close(); // <-- close browser after everything is done
    } catch (error) {
      console.log(error);
    }

以下是它在沙盒上的完美运作方式。 enter image description here

The puppeteer docs是一个开始了解这一点的好地方。