JavaScript (Node.js) 中的 HTML 解析:完整指南
HTML 解析是现代 Web 开发人员的关键技能之一。在 Node.js 生态系统中,有几种强大的工具可用于从 HTML 文档中提取数据。在本文中,我们将详细介绍三个主要库:Cheerio、JSDOM 和 Puppeteer,并学习如何根据具体任务选择合适的工具。
1. Cheerio — 轻量且快速的解析器
Cheerio 是一个快速、灵活且轻量的库,它在服务器端实现了 jQuery 的子集。它非常适合解析静态 HTML,当不需要执行页面上的 JavaScript 时。
安装
npm install cheerio使用示例
const cheerio = require('cheerio');const axios = require('axios');
async function parseHTML() { const response = await axios.get('https://example.com'); const $ = cheerio.load(response.data); // 提取页面标题 const title = $('title').text(); console.log('标题:', title); // 获取所有链接 const links = []; $('a').each((i, el) => { links.push($(el).attr('href')); }); console.log('链接:', links); // 解析表格 const tableData = []; $('table tr').each((i, row) => { const cells = []; $(row).find('td, th').each((j, cell) => { cells.push($(cell).text().trim()); }); tableData.push(cells); }); console.log('表格数据:', tableData);}
parseHTML().catch(console.error);Cheerio 的优点
- 高性能 — 比同类工具快 8 倍
- 熟悉的 jQuery 语法
- 低内存消耗
- 安装和配置简单
缺点
- 不支持动态内容
- 无法执行 JavaScript
- 不适用于 SPA 应用
2. JSDOM — 完整的 DOM 实现
JSDOM 在 Node.js 中模拟浏览器环境,提供完整的 DOM 和 HTML 解析器实现。与 Cheerio 不同,JSDOM 可以执行 JavaScript,因此适用于解析包含动态内容的页面。
安装
npm install jsdom使用示例
const { JSDOM } = require('jsdom');const axios = require('axios');
async function parseWithJSDOM() { const response = await axios.get('https://example.com'); const dom = new JSDOM(response.data); const document = dom.window.document; // 获取所有段落 const paragraphs = Array.from(document.querySelectorAll('p')) .map(p => p.textContent); console.log('段落:', paragraphs); // 处理属性 const images = Array.from(document.querySelectorAll('img')) .map(img => ({ src: img.getAttribute('src'), alt: img.getAttribute('alt') })); console.log('图片:', images); // 执行脚本(谨慎!) const { window } = new JSDOM(`<body> <script> document.body.innerHTML += '<p>动态内容</p>'; </script> </body>`, { runScripts: 'dangerously' }); console.log(window.document.body.innerHTML);}
parseWithJSDOM().catch(console.error);JSDOM 的优点
- 完全支持 DOM API
- 能够执行 JavaScript
- 支持现代 Web 标准
- 与浏览器库兼容
缺点
- 比 Cheerio 慢 \