首页 > 解决方案 > Puppeteer:在评估()中记录 HTML DOM 对象

问题描述

当我运行 puppeteer 脚本时,如果我想在 page.evaluate 中做一个日志,我可以使用如下代码

page.on('console', consoleObj => console.log(consoleObj.text()));

不幸的是,如果我想记录一个对象,它就不起作用:

例如,下面的代码没有正确记录 js obj:

page.on("console", log => {
   console[log._type](log.text());
});

await pageBis.evaluate(() => {
   let selector = `select.form1 option[value="optionToSelect"]`;
   let optionObj = document.querySelectorAll(selector)[0];
   console.log(`optionObj : ${JSON.stringify(optionObj)}`);
});

它显示:

选项对象:{}

请问你知道怎么处理吗?

标签: javascriptnode.jspuppeteergoogle-chrome-headless

解决方案


问题

如果您about:blank在默认浏览器上打开并运行以下命令,

console.log(JSON.stringify(document.querySelector('body')))

它会返回{},因为它试图将 HTML 元素转换为不可能的字符串。

解决方案:domjson

有很多方法可以做到这一点。您可以在浏览器中使用此类库,addScriptTag并根据需要使用控制台输出或使用。

用法:

// add the script to the window like <script src="...">
await page.addScriptTag({url:"https://www.unpkg.com/domjson"})

// run the code inside browser, we have domJSON available on window now
await page.evaluate(()=>{

  // use it
  const bodyJson = domJSON.toJSON(document.querySelector('body'));

  // log it
  console.log(JSON.stringify(bodyJson, true, 2))
})

结果:

{
  "meta": {
    "href": "about:blank",
    "userAgent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.67 Safari/537.36",
    "version": "0.1.2",
    "clock": 1,
    "date": "2018-10-22T15:08:03.973Z",
    "dimensions": {
      "inner": {
        "x": 1920,
        "y": 476
      },
      "outer": {
        "x": 1920,
        "y": 993
      }
    },
...

domjson最后一次在 npm 上发布是 4 年前,但仍然可以满足这个问题的需求,并且可能不会造成任何重大的安全问题,也没有外部依赖项。他们的 github 页面最近一次更新是 20 天前,有几个修复。

笔记:

  • 还有其他几个模块可以处理 dom,例如jsdom等。
  • 无论您在里面做什么.evaluate,它都会在浏览器上下文中运行。
  • 无论你在外面做什么,它都会在nodeJS 上下文中运行。因此,您将不得不以不同的方式对待它们。在此处了解有关上下文的更多信息。
  • DOM 表示HTML DOM(文档对象模型),它(仅)在浏览器中可用,所以如果可能的话最好在那里使用它。

推荐阅读