如何使用nodeJS和Puppeteer解决“目标关闭”错误?

时间:2019-12-06 13:20:22

标签: javascript node.js asynchronous promise puppeteer

我正在尝试抓取和抓取某些网站以提取一些链接。我希望看到所有hrefs打印到我的控制台。但是,相反,出现以下错误。

  

out [承诺{}]   (节点:15908)UnhandledPromiseRejectionWarning:错误:协议错误(Page.navigate):目标已关闭。

我在做什么错了?

This answer says,错误消息表示browser.close()在我致电pageFunction时已经执行。

但是我正在使用async await,显然浏览器仍在关闭我。

如何解决此错误?

const domains = [...]

const pageFunction = async $posts => {
  const data = [];
  await $posts.forEach( $post => {
    data.push( $post.href );
  });
  return data;
}

(async () => {
  // start browser
  const browser = await puppeteer.launch();
  const page = await browser.newPage();

  // loop over domains
  const out = await domains.slice(-1).map( async domain => {
    const url = [ 'http', domain, ].join(joiner2);
    await page.goto( url, waitUntilLoad, );
    const hrefs = await page.$$eval( 'a', pageFunction, );
    return hrefs;
  });

  // log hrefs
  console.log( 'out', out, );
  await browser.close();
})();

另外,请注意:当我使用时:

  const pageFunction = async $posts =>
    await $posts.map( $post => $post.href )

错误消失了。但是我也没有任何输出。我希望控制台记录hrefs,但不记录任何内容。

FWIW:Here is the question I wrote yesterday在同一段代码上。我现在只通过一个URL slice(-1)而不是整个列表来修改代码。现在我得到了上面的错误,而不是我在昨天的问题中描述的错误。

1 个答案:

答案 0 :(得分:1)

我非常确定这是因为在匿名函数中,您正在等待map的结果,该结果立即返回Promises数组。这意味着您的代码执行将继续关闭浏览器。

您应该尝试以下操作:

const promises = domains.slice(-1).map( async domain => {...});
const out = await Promise.all(promises);