如何用Puppeteer提取指定class的DOM元素并正确获取其dataset属性值
问题原因
Puppeteer的浏览器执行上下文与Node.js运行上下文完全隔离,page.$$eval回调函数的返回值必须是可序列化的JSON类型才能跨上下文传递到Node层。你在回调中直接返回DOM节点数组,DOM节点本身不支持序列化,所以Node层拿到的只是空占位对象,无法访问className、dataset等DOM原生属性。
解决方案
方案1:直接在浏览器上下文提取目标值(推荐)
如果仅需要提取dataset.keyword值,直接在$$eval回调中完成属性提取,返回可序列化的数组即可,该方案仅需一次跨上下文通信,效率最高:
// 直接在浏览器侧提取所有s-suggestion元素的dataset.keyword值 const suggestionKeywords = await page.$$eval('.s-suggestion', divs => { return divs.map(div => div.dataset.keyword) }) // 遍历输出结果 for (let n = 0; n < suggestionKeywords.length; n++) { console.log(`n=${n}`) const sKeyword = suggestionKeywords[n] console.log(` - suggestion keyword: ${sKeyword}`) }
方案2:通过ElementHandle读取属性
如果你后续需要对这些元素做点击、输入等交互操作,可以用page.$$获取DOM代理对象,再通过API读取属性:
// 获取元素代理对象数组 const suggestions = await page.$$('.s-suggestion') for (let n=0; n < suggestions.length; n++) { const suggestion = suggestions[n] console.log(`n=${n}`) // 读取className属性 const classNameHandle = await suggestion.getProperty('className') const className = await classNameHandle.jsonValue() console.log(` - suggestion className: ${className}`) // 读取dataset.keyword const datasetHandle = await suggestion.getProperty('dataset') const dataset = await datasetHandle.jsonValue() const sKeyword = dataset.keyword console.log(` - suggestion keyword: ${sKeyword}`) // 用完释放元素句柄,避免内存泄漏 await suggestion.dispose() }
内容的提问来源于stack exchange,提问作者Orville Chomer
相关产品推荐
相关产品推荐

