如何用Puppeteer选择一个块

时间:2018-01-16 18:46:11

标签: javascript html node.js puppeteer

我正在尝试从Puppeteer获取块列表的高度,但我无法在page.evaluate()中选择我的块,因为它会抛出错误。

所以,我有这段代码:

(async () => {
        const browser = await puppeteer.launch();
        const page = await browser.newPage();
        await page.goto(`data:text/html,${html}`);

        for (let property in blockIds) {
            if (blockIds.hasOwnProperty(property)) { console.log(property);
                const height = await page.evaluate(property, () => {
                    return document.getElementById(property).offsetHeight;
                });
                console.log(property, height)
            }
        }

        await browser.close();
    })();
  • html是字符串中的有效HTML页面。
  • blockIds是此类型的对象:{ 'block-id': null, 'block-id-2': null}

我的想法是获得所有块的高度,以便我可以获得此输出: {'block-id': 123, 'block-id-2': 321}

但是当我运行这段代码时,我得到了以下输出 (注意 question-2 是我的blockId)

  

问题-2

     

(node:6338)UnhandledPromiseRejectionWarning:未处理的承诺拒绝(拒绝ID:1):错误:评估失败:ReferenceError:问题未定义       at:1:1

     

(node:6338)[DEP0018]弃用警告:不推荐使用未处理的拒绝承诺。将来,未处理的承诺拒绝将使用非零退出代码终止Node.js进程。

我真的不明白为什么这段代码不起作用,如果我直接在document.getElementById内放置«question-2»,Puppeteer会给我正确的高度。

那么,我错过了什么?

1 个答案:

答案 0 :(得分:0)

  1. 该函数应作为page.evaluate的第一个参数传递,如Puppeteer文档中所示。
  2. https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#pageevaluatepagefunction-args

    1. 传递给page.evaluate的任何参数也必须传递给您传递的函数。 page.evaluate((arg)=>{}, arg);

    2. 使用for...in循环,该值未分配给property,它将分配属性名称。要在for...in循环中访问该值,您应该执行以下操作:blockIds[property]

    3. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in

      总结你得到:

      await page.evaluate((property) => {
          return document.getElementById(property)_.offsetHeight;
      }, blockIds[property])
      

      您可能需要考虑从for...in循环切换到for...of循环。这会将值赋给property,从而允许您更简洁的循环体,因为它也会忽略从原型继承的属性,因此您可以省略.hasOwnProperty检查,因为它不需要。

      https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of

      这将导致:

      for (let property of blockIds) {
          //no need to check for .hasOwnProperty here
          const height = await page.evaluate((property) => {
              return document.getElementById(property).offsetHeight;
          }, property); //no need to use blockIds[property] here
      }