Puppeteer:在 evaluate() 中记录 HTML DOM 对象

Puppeteer: log HTML DOM object in evaluate()

当我 运行 一个木偶脚本时,如果我想在 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)}`);
});

显示:

optionObj : {}

请问你知道怎么处理吗?

问题

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

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

它会 return {},因为它试图将 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 最后一次发布在 4 年前的 npm 上,但仍然可以满足这个问题的需要,并且可能不会造成任何严重的安全问题,也没有外部依赖。他们的 github 页面最近一次更新是在 20 天前,其中包含一些修复。

注:

  • 还有其他几个模块可以处理 dom 比如 jsdom 等等
  • 无论您在 .evaluate 中做什么,它 运行 都在 浏览器上下文 中。
  • 无论你在外面做什么,它都会 运行 在 nodeJS 上下文中 。所以你必须区别对待他们。详细了解上下文 here
  • DOM表示HTMLDOM(文档对象模型),它(仅)在浏览器内部可用,所以最好如果可能的话在那里使用它。