后端也能用 jQuery 爬网页?Cheerio 了解一下
摘要:在 Node.js 后端爬取网页,你还在用正则表达式匹配文本?Cheerio 让你用写 jQuery 的方式解析 HTML,简洁又高效。本文从爬虫基础讲起,用 Cheerio 提取网页内容,再进阶到 LangChain 的 CheerioWebBaseLoader,打通 RAG 知识库的数据入口。
📑 目录
- 数据从哪来?RAG 知识库的"第一公里"
- Cheerio 是什么?服务端的 jQuery
- 原生爬虫:axios + Cheerio 实战
- LangChain 封装:CheerioWebBaseLoader
- 一点总结
- 互动讨论
数据从哪来?RAG 知识库的"第一公里"
构建 RAG 知识库的第一步是:把外部数据"喂"进去。
这些数据可能来自 Word 文档、PDF、数据库,也可能来自网页。而网页是最常见、最丰富的知识来源------技术文档、博客文章、官方公告,大量高质量信息以网页形式存在。
此处插入图片:0CF04CF0-DB92-40E9-BCA9-FC17B4F71FB6.png
这张图展示了 RAG 知识库构建的第一阶段 :Loader 从各种数据源(Word、PDF、URL、YouTube 等)加载内容,标准化为 Document 对象。
网页爬虫要解决的核心问题是:
拿到一个 URL,如何从中提取出干净的正文内容?
Cheerio 是什么?服务端的 jQuery
在 Node.js 后端爬取网页时,我们拿到的是一个 HTML 字符串。要从中提取特定内容,传统方式是用正则表达式:
javascript
css
// ❌ 脆弱、难维护
const title = html.match(/<h1>(.*?)</h1>/)?.[1];
这种方式有两个致命问题:
- 稍有一点格式变化就匹配失败
- 面对复杂 HTML 结构,正则表达式会变成"天书"
Cheerio 解决了这个问题。 它让你在 Node.js 后端用写 jQuery 的方式去解析 HTML:
javascript
javascript
import * as cheerio from 'cheerio';
const $ = cheerio.load('<h2 class="title">Hello world</h2>');
$('h2.title').text(); // "Hello world"
Cheerio 的核心特点:
| 特点 | 说明 |
|---|---|
| 语法熟悉 | API 与 jQuery 高度一致,会 jQuery 就能直接上手 |
| 速度极快 | 不渲染页面、不执行 JS、不加载外部资源,只解析 HTML 字符串 |
| 灵活性高 | 底层可选用 parse5 或 htmlparser2,几乎能解析任何 HTML |
| 跨平台 | 同时支持浏览器和 Node.js 环境 |
关键限制 :Cheerio 不是浏览器。它不渲染页面、不执行 JavaScript、不加载 CSS 或外部资源。如果你的目标网站依赖 JS 动态渲染内容,Cheerio 无法直接抓取,需要考虑 Puppeteer 或 Playwright。
原生爬虫:axios + Cheerio 实战
来试试用 axios 获取 HTML,再用 Cheerio 解析:
javascript
javascript
import axios from 'axios';
import * as cheerio from 'cheerio';
const targetURL = 'https://juejin.cn/post/7662937986766012431';
async function crawlPage() {
try {
// 1. 发送 HTTP 请求,获取 HTML 字符串
const { data: html } = await axios.get(targetURL);
// 2. 在内存中构建 DOM 树
const $ = cheerio.load(html);
// 3. 用 CSS 选择器精准提取
const pageTitle = $('.main-area p').text();
console.log(pageTitle);
} catch(e) {
console.log(e.message);
}
}
crawlPage();
三步走:
| 步骤 | 操作 | 说明 |
|---|---|---|
| ① | axios.get(url) |
向 URL 发送 HTTP 请求,返回 HTML 字符串 |
| ② | cheerio.load(html) |
在内存中把 HTML 字符串解析为 DOM 树 |
| ③ | $('selector').text() |
用 CSS 选择器在 DOM 树中查找目标元素,提取文本 |
这就是 Cheerio 的核心价值:让后端开发者用前端 DOM 操作的思维方式去爬取网页,而不是写复杂的正则表达式。
LangChain 封装:CheerioWebBaseLoader
LangChain 提供了 CheerioWebBaseLoader,进一步封装了爬取 + Cheerio 解析的过程:
javascript
javascript
import { CheerioWebBaseLoader } from '@langchain/community/document_loaders/web/cheerio';
const cheerioLoader = new CheerioWebBaseLoader(
'https://juejin.cn/post/7660683463612743722',
{
selector: '.main-area p' // 只提取这部分内容
}
);
const document = await cheerioLoader.load();
LangChain 封装带来的便利:
| 便利之处 | 说明 |
|---|---|
| 自动封装 | 自动完成 axios.get() + cheerio.load() 的完整流程 |
| 标准化输出 | 自动将提取的内容封装为标准的 Document 对象 |
| 元数据记录 | metadata 中自动记录来源 URL,便于检索时溯源 |
| 选择器精准 | 通过 selector 参数精准控制要提取的内容范围 |
Document 对象的结构:
javascript
css
{
pageContent: '提取到的正文内容...',
metadata: {
source: 'https://juejin.cn/post/7660683463612743722',
// 其他自动添加的元数据
}
}
在 RAG 知识库构建中,爬虫负责 "取数据" ,而 Document 是后续所有流程的标准数据格式。
一点总结
Cheerio = 服务端 jQuery = 用 CSS 选择器从 HTML 中提取数据的工具。
| 概念 | 一句话理解 |
|---|---|
| Cheerio | 在 Node.js 后端,用写 jQuery 的方式解析 HTML |
| 适用场景 | 静态网页内容提取 |
| 不适用场景 | 依赖 JS 动态渲染的网页(需要 Puppeteer) |
| RAG 中的角色 | 把"脏 HTML"洗成"干净纯文本" |
| LangChain 封装 | CheerioWebBaseLoader,自动封装为 Document |
互动讨论
- Cheerio 和 Puppeteer 的核心区别是什么? 什么场景下必须用 Puppeteer?
- 如果目标网站有反爬机制(如 Cloudflare),Cheerio 能绕过吗? 不能的话怎么办?
- LangChain 的
CheerioWebBaseLoader和直接用axios + cheerio相比,有什么优势? metadata中记录source字段有什么用? 在 RAG 回答中如何利用这个信息?
📌 一点心得:爬虫是 RAG 知识库的"第一公里"。数据都取不到,后面的一切都是空谈。Cheerio 让这件事变得简单------用你熟悉的 CSS 选择器,从网页里精准"捞"出需要的内容。