使用Puppeteer与jsdom解析网页HTML遇空数组问题求助
问题解决:Puppeteer+jsdom解析HTML返回空数组的修复方案
核心问题分析
- 你创建JSDOM时传错了参数:
pageData是包含html字段的对象,但JSDOM构造函数需要纯HTML字符串,应该传pageData.html。 - 额外冗余操作:其实没必要用jsdom——Puppeteer本身运行在真实浏览器环境中,直接在
page.evaluate()里就能完成DOM遍历和数据收集,不需要把HTML导出后再二次解析,既浪费资源又容易出问题。
方案一:修复jsdom的用法
修改创建JSDOM的代码,传入正确的HTML字符串:
const doc = new JSDOM(pageData.html, { runScripts: "dangerously" });
如果你的需求是收集所有HTML标签(而非仅body的直接子元素),可以调整遍历逻辑:
const arr = [...doc.window.document.querySelectorAll("*")].map( (el) => el.outerHTML.toString() );
方案二:直接在Puppeteer中完成DOM遍历(更推荐)
完全去掉jsdom,直接在浏览器上下文内完成操作,代码更简洁高效,还能避免跨环境问题:
const express = require("express"); const cors = require("cors"); const puppeteer = require("puppeteer"); const app = express(); app.use(cors()); app.use(express.json()); app.get("/", async (req, res) => { try { const browser = await puppeteer.launch(); const page = await browser.newPage(); await page.goto("https://books.toscrape.com/"); // 直接在浏览器环境中遍历DOM并收集数据 const arr = await page.evaluate(() => { // 按需选择:收集body直接子元素的innerHTML return Array.from(document.body.children).map(child => child.innerHTML.toString()); // 或者收集所有标签的outerHTML(保留标签本身) // return Array.from(document.querySelectorAll("*")).map(el => el.outerHTML); }); await browser.close(); // 必须关闭浏览器,避免内存泄漏 console.log(arr); res.json({ message: arr }); } catch (err) { console.error(err); res.status(500).json({ error: "抓取失败" }); } }); console.log("test"); app.listen(8000, () => { console.log(`Server is running on port 8000.`); });
额外注意事项
- 务必关闭Puppeteer的浏览器实例,否则会造成内存泄漏。
- 增加错误捕获逻辑,避免程序崩溃,同时给前端返回明确的错误提示。
- 明确需求:区分要收集的是「标签本身(用
outerHTML)」还是「标签内的内容(用innerHTML)」,以及是「所有标签」还是「特定层级的标签」。
内容的提问来源于stack exchange,提问作者ecurtis28
相关产品推荐
相关产品推荐

