Puppeteer page.evaluate querySelectorAll 返回空对象

IT技术 javascript node.js google-chrome-devtools puppeteer google-chrome-headless
2021-03-02 12:36:53

我正在试用 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();
3个回答

从评估函数返回的值应该是 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);
不知道你是不是打错了。但是,如果您尝试使用速记符号返回该对象,则需要包装返回对象;await page.evaluate(_ => ({ a: 1 })). 绝对可能是导致未定义的原因。
2021-04-21 12:36:53
我不清楚这些文档,因为它们指向定义的链接,SerializableJSON.stringify定义明确指出对象是可序列化的(显然它们是)。尽管如此,一个简单的await page.evaluate(_ => { a: 1 })将返回undefined
2021-05-13 12:36:53

问题:

的返回值page.evaluate()必须是可序列化的

根据Puppeteer 文档,它说:

如果传递给 的函数page.evaluate返回一个不可序列化的值,则page.evaluate解析为undefinedDevTools协议还支持转移是不可序列通过一些附加valueJSON-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);

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

 await page.evaluate(() => 
       Array.from(document.querySelectorAll('.title'), 
       e => e.href));
TILArray.From需要一个回调映射函数
2021-05-20 12:36:53