You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何在Puppeteer的page.$$eval中无法返回Set类型?

Puppeteer返回Set时得到空对象的原因及解决办法

问题场景

以下代码运行正常,控制台能输出页面链接的数组:

import puppeteer from "puppeteer"
const browser = await puppeteer.launch({ headless: false })

const page = await browser.newPage()
await page.goto("https://www.scrapethissite.com/pages/")

let result = await page.$$eval("body a", (data) => {
  let links = data.map((elem) => elem.href)
  return links
})

console.log(result)

但将回调函数的返回值改为Set对象后,控制台输出的却是空对象{}:

import puppeteer from "puppeteer"
const browser = await puppeteer.launch({ headless: false })

const page = await browser.newPage()
await page.goto("https://www.scrapethissite.com/pages/")

let result = await page.$$eval("body a", (data) => {
  let links = data.map((elem) => elem.href)
  return new Set(links) // 此处修改为返回Set
})

console.log(result) // 输出{}

原因解析

核心问题在于Puppeteer的跨上下文数据传输机制:$$eval的回调函数运行在浏览器的页面上下文,而返回值需要传递到Node.js的主上下文,这个过程会对数据做JSON序列化处理。

但Set属于JavaScript的内置复杂类型,JSON格式并不支持直接序列化Set对象,Puppeteer尝试序列化时,只能得到一个空对象。

解决方法

方法1:将Set转为数组后返回

数组是JSON支持的类型,可以正常完成跨上下文传输,回到Node.js上下文后再重新生成Set:

import puppeteer from "puppeteer"
const browser = await puppeteer.launch({ headless: false })

const page = await browser.newPage()
await page.goto("https://www.scrapethissite.com/pages/")

let result = await page.$$eval("body a", (data) => {
  let links = data.map((elem) => elem.href)
  return Array.from(new Set(links)) // 把Set转成数组返回
})

// 在Node.js侧重新创建Set
const uniqueLinks = new Set(result)
console.log(uniqueLinks)

方法2:在浏览器上下文完成逻辑,返回序列化兼容数据

如果不需要在浏览器侧保留Set结构,可以直接在回调里完成去重等逻辑,返回普通数组或对象:

// 示例:直接返回去重后的数组
let result = await page.$$eval("body a", (data) => {
  return [...new Set(data.map(elem => elem.href))]
})
console.log(result)

内容的提问来源于stack exchange,提问作者Noob

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 04:15:47