javascript - page.evaluate 对比。 Puppeteer $ 方法

标签 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.$$())背后的动机。 .

最佳答案

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

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

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

  • 第二个代码片段只是这样做:
  • 在浏览器上下文中运行给定函数(并将结果返回到 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/

    相关文章:

    javascript - 填充后 MongooseJS 返回空数组

    带有字符串和索引的 JavaScript 类型强制

    javascript - 我可以在 JavaScript 中删除全局变量吗

    docker - 使用 --no-sandbox 运行 headless Chrome/Puppeteer

    javascript - Puppeteer 无法上传文件,出现 TypeError : Failed to fetch

    javascript - Jquery Fancyform 和 IE10 : Checkbox does not get checked when clicking on label

    javascript - 如何使用 REST for Sharepoint 2013 删除项目

    javascript - 删除 npm 包时会发生什么?

    javascript - 在链式 Promise 中,为什么第二个 Promise 在第一个 Promise 之前执行?

    puppeteer - 有没有办法触发标准缩放(不是 headless )