【问题标题】:Getting children of an element in Puppeteer: element.children.length works but element.children returns undefined在 Puppeteer 中获取元素的子元素: element.children.length 有效,但 element.children 返回 undefined
【发布时间】:2022-02-02 01:12:09
【问题描述】:

我有这个代码sn-p:



    const historicalDataTable = await findElementByClass(
      "table",
      elementClass,
      page
    ); // This is a custom function I wrote. Works as expected.


    const tableBody = await historicalDataTable.$eval(
      "tbody",
      (el) => el.children.length
    );

    console.log(tableBody);

这按预期工作并返回正确数量的子项。但是当我这样做时

 const tableBody = await historicalDataTable.$eval(
      "tbody",
      (el) => el.children
    );

并删除长度,它返回未定义。这是怎么回事?

【问题讨论】:

    标签: node.js puppeteer


    【解决方案1】:

    el.children (Element#children) 将产生一个HTMLCollection,它不可序列化并且无法从页面的执行上下文编组到您的上下文中,因此evaluate 将返回undefined

    现在,在查看 elementHandle.$eval docs 时,这并不完全明显,因为唯一的迹象是返回值是 <Promise<Serializable>>,但从 executionContext.evaluate docs 可以清楚地看出:

    • 返回:PromiseSerializable>> Promise 解析为 pageFunction 的返回值

    [...]

    如果传递给executionContext.evaluate 的函数返回非Serializable 值,则executionContext.evaluate 解析为undefined DevTools 协议还支持传输一些不可序列化的附加值by JSON: -0, NaN, Infinity, -Infinity, 和 bigint 字面量。

    (强调我的。)

    另一方面,el.children.length (HTMLCollection#length) 是一个简单的number可序列化的。

    您必须对 pageFunction 中的这些元素做任何您想做的事情,并且只返回一些可序列化的值。

    或者,您也可以使用elementHandle.evaluateHandleJSHandle 返回到HTMLCollection,并在稍后再次调用evaluate 类型的函数时使用该句柄。 (请注意,这将是唯一 您可以用它做的事情。例如,您无法从您自己的执行上下文访问.length,只能从另一个pageFunction1.)


    1: 这并不完全正确,因为您可以例如使用jsHandle.getPropertylength 获取另一个JSHandle,然后使用jsHandle.jsonValue 来获取值作为数字 - 但是这两个操作都是异步的,并且编写代码的效率可能要高得多,这样您就可以首先在页面的执行上下文中处理所有必要的操作,而无需太多的上下文切换。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-22
      • 1970-01-01
      • 2013-05-19
      • 1970-01-01
      • 1970-01-01
      • 2020-07-07
      • 1970-01-01
      • 2019-04-01
      相关资源
      最近更新 更多