【问题标题】:Puppeteer page.evaluate querySelectorAll return empty objectsPuppeteer page.evaluate querySelectorAll 返回空对象
【发布时间】:2018-03-04 19:32:58
【问题描述】:

我正在尝试 Puppeteer。这是您可以运行的示例代码:https://try-puppeteer.appspot.com/

问题是这段代码返回一个空对象数组:

[{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{ },{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{}, {}、{}、{}、{}、{}、{}、{}、{}、{}、{}、{}、{}、{}、{}、{}、{}、{} ,{},{},{},{},{},{},{},{}]

我是不是搞错了?

const browser = await puppeteer.launch();

const page = await browser.newPage();
await page.goto('https://reddit.com/');

let list = await page.evaluate(() => {
  return Promise.resolve(Array.from(document.querySelectorAll('.title')));
});

console.log(JSON.stringify(list))

await browser.close();

【问题讨论】:

    标签: javascript node.js google-chrome-devtools puppeteer google-chrome-headless


    【解决方案1】:

    evaluate 函数返回的值应该是 json 可序列化的。 https://github.com/GoogleChrome/puppeteer/issues/303#issuecomment-322919968

    解决方案是从元素中提取 href 值并返回。

     await this.page.evaluate((sel) => {
            let elements = Array.from(document.querySelectorAll(sel));
            let links = elements.map(element => {
                return element.href
            })
            return links;
        }, sel);
    

    【讨论】:

    • 我不清楚这些文档,因为它们与Serializable 的链接指向JSON.stringify 定义,该定义明确指出对象是可序列化的(显然它们是可序列化的)。尽管如此,一个简单的await page.evaluate(_ => { a: 1 }) 将返回undefined
    • 不确定您是否输入错误。但是,如果您尝试使用速记符号返回该对象,则需要包装返回对象; await page.evaluate(_ => ({ a: 1 }))。绝对可能是导致未定义的原因。
    【解决方案2】:

    问题:

    page.evaluate() 的返回值必须是 serializable

    根据Puppeteer documentation,它说:

    如果传递给page.evaluate 的函数返回非Serializable 值,则page.evaluate 解析为undefined。 DevTools 协议还支持传输一些 JSON 无法序列化的附加值:-0NaNInfinity-Infinity 和 bigint 文字。

    换句话说,您不能将页面 DOM 环境中的元素返回到 Node.js 环境,因为它们是分开的。

    解决方案:

    您可以将ElementHandle(表示页内 DOM 元素)返回给 Node.js 环境。

    使用page.$$() 获取ElementHandle 数组:

    let list = await page.$$('.title');
    

    否则,如果你想从元素中提取href的值并返回,你可以使用page.$$eval()

    let list = await page.$$eval('.title', a => a.href);
    

    【讨论】:

      【解决方案3】:

      我遇到了类似的问题,我是这样解决的;

       await page.evaluate(() => 
             Array.from(document.querySelectorAll('.title'), 
             e => e.href));
      

      【讨论】:

      • TIL Array.From 采用回调映射函数
      猜你喜欢
      • 1970-01-01
      • 2020-07-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-25
      相关资源
      最近更新 更多