Puppeteer page.evaluate querySelectorAll 返回空对象

Posted

技术标签:

【中文标题】Puppeteer page.evaluate querySelectorAll 返回空对象【英文标题】:Puppeteer page.evaluate querySelectorAll return empty objects 【发布时间】: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();

【问题讨论】:

【参考方案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 采用回调映射函数

以上是关于Puppeteer page.evaluate querySelectorAll 返回空对象的主要内容,如果未能解决你的问题,请参考以下文章

Puppeteer:将元素句柄数组发送到page.evaluate

Puppeteer page.evaluate querySelectorAll 返回空对象

如何将变量传递给评估函数?

获取在 Puppeteer 中悬停的链接的 href

如何在chrome headless + puppeteer评估()中使用xpath?

在phantom.js中同步page.evaluate