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
无法序列化的附加值:-0
、NaN
、Infinity
、-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));
【讨论】:
TILArray.From
采用回调映射函数以上是关于Puppeteer page.evaluate querySelectorAll 返回空对象的主要内容,如果未能解决你的问题,请参考以下文章
Puppeteer:将元素句柄数组发送到page.evaluate
Puppeteer page.evaluate querySelectorAll 返回空对象