page.vs. Puppeteer $方法

时间:2019-04-13 10:22:19

标签: javascript node.js puppeteer

我对这两个代码块的差异很感兴趣。

const $anchor = await page.$('a.buy-now');
const link = await $anchor.getProperty('href');
await $anchor.click();
await page.evaluate(() => {
    const $anchor = document.querySelector('a.buy-now');
    const text = $anchor.href;
    $anchor.click();
});

我通常发现page.evaluate()中的原始DOM元素更容易使用,而$方法返回的ElementHandles是到目前为止的抽象。

但是我也许觉得异步Puppeteer方法可能更高效或更可靠?我在文档中找不到关于此的任何指导,并且有兴趣了解有关每种方法的专业人士/专业人士的更多信息以及添加诸如page.$$()之类的方法背后的动机。

1 个答案:

答案 0 :(得分:3)

这些代码行之间的主要区别是Node.js与浏览器环境之间的交互。

第一个代码段将执行以下操作:

  • 在浏览器中运行document.querySelector并返回元素句柄(返回到Node.js环境)
  • 在该句柄上运行getProperty并将结果返回(返回到Node.js环境)
  • 在浏览器中单击一个元素

第二个代码段只是这样做:

  • 在浏览器上下文中运行给定函数(并将结果返回到Node.js环境)

性能

关于这些语句的性能,必须记住木偶戏通过WebSockets与浏览器进行通信。因此,由于只有一个命令发送到浏览器(而不是三个),因此第二条语句将运行得更快。

如果要连接的浏览器在另一台计算机上运行(使用puppeteer.connect连接),则可能会有很大的不同。如果脚本和浏览器位于同一台计算机上,则可能只会导致几毫秒的差异。因此,在后一种情况下,可能不会有太大的改变。

使用元素句柄的优势

使用元素句柄具有一些优点。首先,与使用document.querySelector('...').click()相比,像elementHandle.click这样的函数将表现得更像“人类”。例如,puppeteer会将鼠标移动到该位置并单击元素的中心,而不仅仅是执行click函数。

什么时候使用什么

通常,我建议尽可能使用page.evaluate,因为此API调试起来也容易得多。发生错误时,您只需在Chrome浏览器中打开DevTools,然后在浏览器中重新运行相同的行即可重现该错误。如果将大量page.$语句混合在一起,可能很难理解问题所在以及它是否在Node.js或浏览器运行时中发生。

如果需要更长的时间,请使用元素句柄(因为您可能已经进行了一些复杂的计算,或者等待外部事件才能从中提取信息)。