爬虫架构的三代演进:从 cheerio 到 Agent 再到 Crawl4AI
做政府/部委政策抓取 1 年,我们的爬虫架构经历了三次大的演进。这篇文章复盘三代爬虫的设计决策、成本数据和踩过的坑,希望对做类似场景(多站点、政策合规、Agent 工程化)的同学有参考价值。
一、背景:为什么”政策爬虫”是个难题
去年加入贝斯平,做的第一个 AI 项目是 Chatomni 政策洞察智能体——给合规部门用的”政策 Copilot”,用户问”营改增对小微企业有什么影响”,系统自动检索最新的政府文件、解读条款、输出结构化建议。
这套系统的输入是政策文件,而政策文件来自政府/部委网站——50+ 个站点、每月新增 1 万+ 政策、单条平均 3-5 KB。
听起来是个”标准的爬虫需求”,但真做起来全是坑:
- 站点改版频繁:某部委网站一年改版 3 次,每次改版 CSS selector 全部失效
- JS 渲染:~40% 的站点是 SPA,cheerio 直接抓不到内容
- 反爬对抗:高频访问触发 IP 黑名单
- 结构差异大:每个站点的”政策列表页 + 详情页”结构都不一样
- 新站点接入慢:每加一个站点,1 个工程师调 selector + 写测试要 1 人天
一年下来,我们的爬虫架构迭代了三代。
二、第一代:cheerio 经典流水线(2025.09 – 2025.10)
最朴素的做法:每个站点写一份 selector 配置 + cheerio 解析 + 定时调度。
1 | const siteConfig = { |
优点:
- 简单稳定,单个工程师 2 小时上手
- 速度快(秒级抓一个页面)
- 几乎零成本(纯 Node.js,无 LLM 调用)
致命问题:
- ❌ 新站点接入 1 人天/个:每个站点都要人工调 selector + 写单元测试
- ❌ 站点改版即崩溃:CSS selector 一变,爬虫全废,维护成本线性增长
- ❌ **JS 渲染站点覆盖率 0%**:40% 的站点直接抓不到内容
跑了 2 周,新加 5 个站点花了 5 人天,而且半夜被 oncall 叫醒 3 次——都是站点改版导致 selector 失效。
三、第二代:Claude Agent SDK 自决策爬虫(2025.10 – 2025.12)
痛定思痛,决定换思路:让 LLM 自己决定怎么抓。
架构
用 Claude Agent SDK 设计了一个站点分析 Skill,让 Agent 自己分析 HTML 结构、自己写 selector、自己验证。
1 | const agent = new ClaudeAgent({ |
效果
| 指标 | 第一代 cheerio | 第二代 Agent |
|---|---|---|
| 新站点接入成本 | 1 人天 | 0(Agent 自动适配) |
| 站点改版适应成本 | 1 人天/次 | 0(自动重新分析) |
| JS 渲染站点覆盖率 | 0% | ~90% |
| 抓取成功率 | ~85% | ~95% |
| 单条抓取成本 | < ¥0.001 | ¥0.05 – 0.10 |
看起来很美好——Agent 解决了所有问题。
烧钱的过程
但跑了一个月后,账单让我傻眼了:
- 50 个站点 × 每天 1 次 Agent 分析 × ¥0.07/次 = ¥105/月
- 还有 ~5% 的失败站点 fallback 重跑 = ¥15/月
- 总成本:¥120/月,仅爬虫一项
这还只是爬虫,不包含 RAG 检索、问答生成的成本。更糟的是:
- Agent 跑一次站点分析要 5-15 秒(50 个站点排队跑要 10+ 分钟)
- Agent 输出不稳定(同样的输入偶尔会给出不同的 selector 路径)
- 失败排查困难(要看 LLM 思考过程才知道哪步走偏)
四、第三代:Crawl4AI + LiteLLM(2025.12 – 至今)
第二代的本质问题:让 LLM 干”机械活”是杀鸡用牛刀。
Agent 擅长的是”需要推理的复杂决策”,但抓取列表页这件事有固定模式:访问 URL → 找列表项 → 找详情链接 → 访问详情 → 提取字段。这不需要推理,需要的是快速、稳定的规则化抽取。
于是引入了 Crawl4AI——一个专门为 LLM 时代设计的爬虫框架,核心能力:
- headless Chromium 渲染(自动处理 JS)
- CSS selector + XPath + LLM 抽取 三种模式
- 内置反爬对抗(UA 轮换、代理池)
- 结构化输出(JSON Schema 强类型)
新架构
1 | import asyncio |
关键设计:Agent 作为救火 fallback
完全抛弃 Agent 不现实——Crawl4AI 在某些复杂站点(嵌套 iframe、强反爬)还是会失败。
最终架构是 Crawl4AI 为主 + Agent 救火:
1 | async def smart_crawl(site_config): |
为了让 Crawl4AI 和 Agent 结果对齐,加了 shadow mode 影子模式:
1 | # 新方案上线前,并行跑一周对比 |
shadow 模式跑了一周,结果:
- 内容一致性:96.5%
- Crawl4AI 比 Agent 多抓了 ~2% 的”边缘 case”(新格式的附件等)
- 结论:完全可以切到 Crawl4AI
最终效果
| 指标 | 第一代 cheerio | 第二代 Agent | 第三代 Crawl4AI |
|---|---|---|---|
| 新站点接入成本 | 1 人天 | 0 | 0 |
| 站点改版适应成本 | 1 人天/次 | 0 | 0 |
| JS 渲染覆盖率 | 0% | 90% | 98% |
| 抓取成功率 | 85% | 95% | 97% |
| 单条成本 | < ¥0.001 | ¥0.07 | ¥0.004 |
| 月成本(50 站点) | < ¥1 | ¥120 | ¥15 |
五、踩过的坑(写给后来的同学)
坑 1:不要让 LLM 干机械活
Agent 不是万能的。让 LLM 做需要推理的事(理解用户意图、规划工具调用、生成结构化内容),别让它做重复的机械活(CSS selector、HTML 解析、HTTP 请求)。
Agent 跑站点分析一次要 ¥0.07,Crawl4AI 跑一次 ¥0.004——17 倍的成本差距,质量反而 Crawl4AI 更稳定。
坑 2:一定要做 Shadow Mode 对比
切新方案前绝不能直接切换。Shadow mode(影子模式)是让你跑新方案的同时保留旧方案,对比结果差异。
我们的 96.5% 一致性数据,让切换决策有了底气。如果不做 shadow,你永远不知道新方案在哪里偷偷掉了内容。
坑 3:成本失控是静悄悄的
第二代 Agent 跑了一个月才意识到烧了 ¥120。如果做每日成本告警(成本超过阈值就报警),可能一周就能发现。
1 | # Prometheus 告警规则 |
坑 4:失败排查必须有 trace
Agent 失败时,最难的是”它到底哪一步走偏了”。我们后来接入了 LangSmith 做 Agent trace,把每一步的 input/output/latency/token cost 都记下来:
1 | [Step 1] fetch_url("https://...") |
没有 trace,Agent 失败就是”它说不通”;有了 trace,每一步都可解释、可修复。
六、总结:选择爬虫方案的决策树
1 | 你的场景是什么? |
核心原则:
- 能用规则就别用 LLM:成本差 10-100 倍
- Agent 是手术刀,不是锤子:只在需要推理的地方用
- Shadow Mode 是切换方案的护身符:别裸切
- 成本监控要早做:等账单来了就晚了
七、参考资料
作者:魏远标,贝斯平 AI 架构师,13 年 To B 软件架构经验,最近 2 年聚焦 AI Native 应用架构。技术博客:javai.tech
欢迎在评论区交流你的爬虫架构演进经验~