我对这两个代码块的差异感兴趣。
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.$$()
)背后的动机。 .
最佳答案
这些代码行之间的主要区别在于 Node.js 和浏览器环境之间的交互。
第一个代码片段将执行以下操作:
document.querySelector
在浏览器中返回元素句柄(到 Node.js 环境)getProperty
在句柄上并返回结果(到 Node.js 环境)第二个代码片段只是这样做:
表现
关于这些语句的性能,必须记住 puppeteer 通过 WebSockets 与浏览器进行通信。因此,第二个语句将运行得更快,因为只有一个命令发送到浏览器(相比之下,三个)。
如果您要连接的浏览器在不同的机器上运行(使用
puppeteer.connect
连接),这可能会产生很大的不同。如果脚本和浏览器位于同一台机器上,它可能只会导致几毫秒的差异。在后一种情况下,它可能不会有很大的不同。使用元素句柄的优势
使用元素句柄有一些优点。首先,像
elementHandle.click
这样的函数与使用 document.querySelector('...').click()
相比,会表现得更像“人类” .例如,puppeteer 将鼠标移动到该位置并单击元素的中心,而不是仅仅执行 click
功能。什么时候用什么
一般来说,我建议使用
page.evaluate
只要有可能,因为这个 API 也更容易调试。发生错误时,您可以通过在 Chrome 浏览器中打开 DevTools 并在浏览器中重新运行相同的行来简单地重现错误。如果你混合了很多 page.$
语句放在一起可能更难理解问题是什么以及它是否发生在 Node.js 或浏览器运行时中。如果您需要更长时间的元素,请使用元素句柄(因为您可能已经进行了一些复杂的计算或等待外部事件,然后才能从中提取信息)。
关于javascript - page.evaluate 对比。 Puppeteer $ 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55664420/