Crawl4AI:专为 LLM 设计的智能网页抓取器

Crawl4AI:专为 LLM 设计的智能网页抓取器

智能体

📖 简介

Crawl4AI 是专为 LLM 设计的开源网页爬虫,自动把网页转为干净的 Markdown/JSON。20k+ Stars,直接适配 RAG 与 Agent 数据管道,比通用爬虫更懂 AI 应用的数据需求。

📝 详细介绍

一、开篇:10 万条内部文档的智能问答,卡在了"喂数据"这一步

上季度我们给公司做内部知识库 RAG 系统,数据源是散落在内网 Wiki、产品站点和几个老旧 CMS 里的10 万+页面。痛点很直接:文档是 HTML,但里面有大量导航、广告位、JS 动态渲染内容,直接喂给 Embedding 模型,token 浪费严重、语义被噪音污染,经常答非所问。最初我们靠人力清洗,三个人干了一周才整理了不到 5000 页,根本撑不起"全量智能问答"的目标。

二、需求拆解

把业务问题翻译成技术需求,核心是四条:

  • 数据清洗:HTML → Markdown / 纯文本,剔除导航、页脚、脚本标签,保留正文结构
  • 吞吐性能:10 万页全量刷新周期 ≤ 3 天,单页平均抓取+解析 ≤ 2s(估算)
  • 成本和资源约束:内网单台 8C16G 服务器,不能上大规模 Selenium 浏览器集群
  • 可维护性:支持登录态、动态渲染页面,失败需可重试,不能崩了就要人工重跑

三、方案设计:为什么选 Crawl4AI

我对比了三个方案:

  • Scrapy:性能不错,但处理动态内容要接 Splash/Playwright,配置成本高,而且它对"LLM 友好输出"没有任何内置抽象,Markdown 转换还得自己写管线。
  • Playwright + BeautifulSoup:灵活,但自己管浏览器生命周期、并发调度、重试策略,开发量相当于写了半个爬虫框架。
  • Crawl4AI:核心卖点是"专为 LLM 设计"。它原生异步(AsyncWebCrawler),内置 Markdown 生成策略(pruning / filtered 模式)、CSS 选择器定位正文、结构化抽取,还支持用同一个浏览器上下文处理登录态。相当于把爬虫框架和清洗器合二为一,我只需要写业务逻辑,不用搭骨架。

取舍也很明确:我用它做"抓取+清洗"链路,向量化和检索仍然用自建的 Embedding + pgvector,这样 Crawl4AI 只是一个充分解耦的数据管道上游,将来换掉也不会伤筋动骨。

四、落地实现

1. 数据准备

我先分析了目标站点结构,整理出三类页面:静态文章页(Wiki)、动态渲染页(公司产品官网 Vue 应用)、需登录下载的资料页。写了一个 sitemap.txt 白名单,并标记哪些域名需要先注入 Cookie 到浏览器上下文。

# 准备入口 URL,支持从 sitemap 导入
cat > seed_urls.txt <<EOF
https://wiki.internal.example.com/sitemap.xml
https://docs.example.com/sitemap.xml
EOF

2. 构建核心抓取器

引入关键依赖,先写单页验证流程:

import asyncio
from crawl4ai import AsyncWebCrawler, BrowserConfig, CrawlerRunConfig
from crawl4ai.markdown_generation_strategy import DefaultMarkdownGenerator

browser_cfg = BrowserConfig(
    headless=True,
    use_persistent_context=True,          # 复用登录态
    user_data_dir="/data/chrome-profile"
)


run_cfg = CrawlerRunConfig(
    markdown_generator=DefaultMarkdownGenerator(
        options={"ignore_links": True}
    ),
    exclude_selector="nav, footer, form, script, style, .breadcrumb, .sidebar",
    content_selector="article, main, .content",   # 优先在正文容器里提取
    wait_until="domcontentloaded",
    page_timeout=15000,
    remove_overlay_elements=True                 # 去掉 cookie 弹窗、modal
)

async def main():
    async with AsyncWebCrawler(config=browser_cfg) as crawler:
        result = await crawler.arun(
            url="https://docs.example.com/products/order-api",
            config=run_cfg
        )
        if result.success:
            with open("order-api.md", "w", encoding="utf-8") as f:
                f.write(result.markdown.raw_markdown)
        else:
            print(result.error_message)

asyncio.run(main())

单页验证通过后,批量执行时用 arun_many,并配合信号量控制并发,避免打爆内网服务:

async def crawl_all(urls: list[str]) -> int:
    success = 0
    async with AsyncWebCrawler(config=browser_cfg) as crawler:
        # Crawl4AI 的 BatchConfig 管理并发(v0.7+)
        batch = BatchConfig(max_concurrency=8)
        results = await crawler.arun_many(urls, config=run_cfg, batch_config=batch)
        for r in results:
            if r.success:
                # 写入以文档 ID 命名的 Markdown 文件
                with open(f"output/{r.metadata.get('id', hash(r.url))}.md", "w") as f:
                    f.write(r.markdown.raw_markdown)
                success += 1
    return success

3. 部署与调度

内网环境直接跑 Python 进程,用 Docker 固定依赖。Playwright 的浏览器内核单独安装:

FROM python:3.11-slim
RUN pip install crawl4ai playwright && 
    playwright install --with-deps chromium
COPY . /app
WORKDIR /app
CMD ["python", "pipeline.py"]
# 调度:每日凌晨 2 点全量刷新
0 2 * * * cd /app && /usr/local/bin/python pipeline.py --source sitemap.txt --mode full >> logs/crawl.log 2>&1

五、效果与数据

上线两周后,我们跑了 2 轮全量刷新,对比旧方案(手工整理 + 简单爬虫)的数据如下(估算值已标注):

指标 上线前(混合人工+简单脚本) 使用 Crawl4AI 后
单页平均抓取+清洗耗时(估算) 8.5s 2.1s
每页平均 token 消耗(原始 HTML vs Markdown) ~8000 token ~1200 token
全量刷新周期(10 万页) 超过 2 周 约 2.5 天
成功抓取 / 可解析率 78%(大量动态页丢失) 95.3%
人力介入次数(每周) 3~4 次 0~1 次
🚀

AI 项目推荐

智能体
标签
#网页抓取 #数据管道 #RAG #LLM
浏览
👁️ 1
发布日期
2026-08-06