【问题标题】:page.evaluate Vs. Puppeteer $ methodspage.evaluate 对比。 Puppeteer $ 方法
【发布时间】:2019-09-03 23:22:30
【问题描述】:

我对这两个代码块的区别感兴趣。

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.$$() 等方法的动机。

【问题讨论】:

    标签: javascript node.js puppeteer


    【解决方案1】:

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

    第一个代码 sn -p 将执行以下操作:

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

    第二个代码 sn-p 就是这样做的:

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

    性能

    关于这些语句的性能,必须记住 puppeteer 通过 WebSockets 与浏览器进行通信。因此,第二个语句运行得更快,因为只有一个命令发送到浏览器(相比之下,三个)。

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

    使用元素句柄的优势

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

    什么时候用什么

    一般来说,我建议尽可能使用page.evaluate,因为这个 API 也更容易调试。发生错误时,您可以通过在 Chrome 浏览器中打开 DevTools 并在浏览器中重新运行相同的行来简单地重现错误。如果您将大量 page.$ 语句混合在一起,则可能更难以理解问题是什么,以及问题是发生在 Node.js 内部还是浏览器运行时。

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

    【讨论】:

    • 哇,哇!很好的回应,亲爱的。为什么官方文档中没有讨论这些事情?否则,把摘录寄给我,我从现在起就闭上手指。感谢您的澄清。
    • 当我在 vscode 中设置断点并且我只有元素句柄或者我必须使用评估时,是否可以以某种方式突出显示 chrome 中的 html 元素?
    • 这个很好的答案。
    猜你喜欢
    • 2021-02-05
    • 1970-01-01
    • 2018-03-04
    • 2018-02-22
    • 2020-07-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多