惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Apple Machine Learning Research
Apple Machine Learning Research
T
Tailwind CSS Blog
月光博客
月光博客
爱范儿
爱范儿
有赞技术团队
有赞技术团队
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
aimingoo的专栏
aimingoo的专栏
GbyAI
GbyAI
腾讯CDC
The Cloudflare Blog
人人都是产品经理
人人都是产品经理
MongoDB | Blog
MongoDB | Blog
Microsoft Azure Blog
Microsoft Azure Blog
IT之家
IT之家
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
云风的 BLOG
云风的 BLOG
U
Unit 42
博客园 - 三生石上(FineUI控件)
A
About on SuperTechFans
N
Netflix TechBlog - Medium
Google DeepMind News
Google DeepMind News
雷峰网
雷峰网
L
LangChain Blog

BlogFinder

日常漫步 Vol.24 之漫步前山河 - 雅余 周报 #1-聊聊本周的收获 - Edwin's Blog 我的OpenCode必装插件与Skill Write Something 掌中之物未必在掌握之中 · CRIVU PiliNara,一个更顺手的 PiliPlus 分支 「NekoEcho」:做一个必有回响的猫娘主题博客 2026-05 书影音总结 简化博客主题 - 安迪 你要加油呐 我第一次发布 npm 包 拾花小记#45:中考前的二三事 – 小改学习志 黛西花园5月游 #18 枇杷又熟了的五月月报 一些奇奇怪怪的需求?word仿方正书版的几个小操作 - Xiobb's Blog 0419 御温泉之旅 修复了一些bug,网站基本上趋于稳定了 - 新锐博客 又回到四十年前 如何定义成功 迷鹿屋2026已重新上线 科技冰火两重天+一周回顾 ${title} 热度退了,我反而用得更深了-咕咚同学 我到底该不该换个域名? 随身WIFI折腾记 - 安迪 博客撰写体验提升——hexo pro插件 为什么不用相机把屏幕上的接关密码拍下来? 国清寺与天台山 – Ouroboros ★★★★☆《挽救计划》——久违的经济上行感 - Davidの3号基地 删除右键“打开方式”里多余选项
Crawl4AI:专为 LLM 设计的开源 Web 爬虫与数据抓取工具
Cheman · 2026-05-29 · via BlogFinder

一、项目概述

Crawl4AI(GitHub: unclecode/crawl4ai)是一款专为 LLM(大型语言模型)优化的开源 Web 爬虫与数据抓取工具。该项目在 GitHub 上已获得超过 50,000 Star,是最受欢迎的开源爬虫项目之一。

核心特性

  • LLM 友好的输出:智能 Markdown 生成,保留标题、表格、代码和引用标记
  • 高性能架构:异步浏览器池、智能缓存、最小化跳转
  • 完全可控:支持会话管理、代理、Cookie、用户脚本和钩子函数
  • 自适应智能:自动学习网站结构,只探索相关内容
  • 灵活部署:零密钥要求,支持 CLI、Docker,云友好

Crawl4AI 的核心价值在于将网页内容转换为干净的、结构化的 Markdown 格式,这种格式特别适合:

  • **RAG(检索增强生成)**系统
  • AI Agent 的数据获取
  • 数据管道的预处理环节

二、技术原理

2.1 架构设计

Crawl4AI 采用异步架构,基于 Playwright 实现浏览器自动化,核心组件如下:

┌─────────────────────────────────────────┐
│   AsyncWebCrawler (核心爬虫引擎)        │
├─────────────────────────────────────────┤
│  - BrowserConfig (浏览器配置)           │
│  - CrawlerRunConfig (爬取配置)         │
│  - 浏览器池管理                         │
└─────────────────────────────────────────┘
           ↓
┌─────────────────────────────────────────┐
│   内容处理管道                           │
├─────────────────────────────────────────┤
│  1. HTML 抓取 → 2. Markdown 生成      │
│  3. 内容过滤 (Pruning/BM25)           │
│  4. 结构化数据提取 (CSS/LLM)          │
└─────────────────────────────────────────┘

2.2 核心技术栈

技术用途选型理由
Python 3.10+主开发语言异步支持、丰富的生态
Playwright浏览器自动化跨浏览器、稳定的 CDP 支持
asyncio异步并发高效处理大量请求
LiteLLM多 LLM 支持统一接口调用各种 LLM
BM25/余弦相似度内容相关性智能过滤无关内容

2.3 Markdown 生成策略

Crawl4AI 提供两种 Markdown 输出:

  1. Raw Markdown:完整的页面内容
  2. Fit Markdown:经过启发式过滤的精简版本,去除噪声和无关部分
from crawl4ai import AsyncWebCrawler, BrowserConfig, CrawlerRunConfig
from crawl4ai.content_filter_strategy import PruningContentFilter

# 使用 PruningContentFilter 生成 Fit Markdown
browser_config = BrowserConfig(headless=True, verbose=True)
run_config = CrawlerRunConfig(
    markdown_generator=DefaultMarkdownGenerator(
        content_filter=PruningContentFilter(
            threshold=0.48,
            threshold_type="fixed",
            min_word_threshold=0
        )
    )
)

async with AsyncWebCrawler(config=browser_config) as crawler:
    result = await crawler.arun(url="https://example.com", config=run_config)
    print(result.markdown.fit_markdown)  # 精简后的内容

2.4 深度爬取策略

Crawl4AI 支持三种深度爬取策略:

  • BFS (广度优先):逐层遍历
  • DFS (深度优先):优先深入单个路径
  • BestFirst (最佳优先):基于相关性评分优先爬取
from crawl4ai.deep_crawling import BFSDeepCrawlStrategy

strategy = BFSDeepCrawlStrategy(
    max_depth=3,
    max_pages=20,
    include_external=False
)

async with AsyncWebCrawler() as crawler:
    result = await crawler.arun(
        url="https://docs.example.com",
        config=CrawlerRunConfig(deep_crawl_strategy=strategy)
    )
    print(f"爬取了 {len(result.links['internal'])} 个内部链接")

三、安装与快速开始

3.1 环境要求

  • Python 3.10 或更高版本
  • pip 包管理器
  • (可选)Docker 用于容器化部署

3.2 安装步骤

基础安装

# 安装 Crawl4AI
pip install -U crawl4ai

# 运行安装后设置(自动安装 Playwright 浏览器)
crawl4ai-setup

# 验证安装
crawl4ai-doctor

如果遇到浏览器相关问题,可以手动安装:

python -m playwright install --with-deps chromium

3.3 最简运行示例

Python API 方式

import asyncio
from crawl4ai import *

async def main():
    async with AsyncWebCrawler() as crawler:
        result = await crawler.arun(
            url="https://www.nbcnews.com/business",
        )
        print(result.markdown)

if __name__ == "__main__":
    asyncio.run(main())

命令行方式

# 基础爬取,输出 Markdown
crwl https://www.nbcnews.com/business -o markdown

# 深度爬取(BFS 策略,最多 10 页)
crwl https://docs.crawl4ai.com --deep-crawl bfs --max-pages 10

# 使用 LLM 提取特定信息
crwl https://www.example.com/products -q "提取所有产品价格"

四、使用方法与实战

4.1 基础用法

4.1.1 执行 JavaScript

对于需要动态加载内容的页面,可以执行自定义 JavaScript:

import asyncio
from crawl4ai import AsyncWebCrawler, BrowserConfig, CrawlerRunConfig

async def main():
    browser_config = BrowserConfig(headless=False, verbose=True)
    run_config = CrawlerRunConfig(
        js_code="""
        (async () => {
            // 滚动到底部加载更多内容
            await new Promise(resolve => {
                let totalHeight = 0;
                const distance = 100;
                const timer = setInterval(() => {
                    window.scrollBy(0, distance);
                    totalHeight += distance;
                    if(totalHeight >= document.body.scrollHeight){
                        clearInterval(timer);
                        resolve();
                    }
                }, 100);
            });
        })();
        """,
        cache_mode=CacheMode.BYPASS
    )
    
    async with AsyncWebCrawler(config=browser_config) as crawler:
        result = await crawler.arun(
            url="https://example.com/infinite-scroll",
            config=run_config
        )
        print(result.markdown)

if __name__ == "__main__":
    asyncio.run(main())

4.1.2 使用浏览器配置文件中

Crawl4AI 支持使用真实的浏览器配置文件,绕过 bot 检测:

import os
from pathlib import Path
import asyncio
from crawl4ai import AsyncWebCrawler, BrowserConfig, CrawlerRunConfig

async def main():
    # 创建持久化的用户数据目录
    user_data_dir = os.path.join(Path.home(), ".crawl4ai", "browser_profile")
    os.makedirs(user_data_dir, exist_ok=True)

    browser_config = BrowserConfig(
        verbose=True,
        headless=True,
        user_data_dir=user_data_dir,
        use_persistent_context=True,
    )
    run_config = CrawlerRunConfig(
        cache_mode=CacheMode.BYPASS
    )
    
    async with AsyncWebCrawler(config=browser_config) as crawler:
        url = "https://需要登录的网站.com"
        
        result = await crawler.arun(
            url,
            config=run_config,
            magic=True,  # 自动处理常见反爬措施
        )
        
        print(f"成功爬取 {url}")
        print(f"内容长度: {len(result.markdown)}")

if __name__ == "__main__":
    asyncio.run(main())

4.2 进阶用法

4.2.1 结构化数据提取(无 LLM)

使用 CSS 选择器提取结构化数据:

import asyncio
from crawl4ai import AsyncWebCrawler, BrowserConfig, CrawlerRunConfig
from crawl4ai import JsonCssExtractionStrategy
import json

async def main():
    schema = {
        "name": "课程列表",
        "baseSelector": "section.charge-methodology .w-tab-content > div",
        "fields": [
            {
                "name": "section_title",
                "selector": "h3.heading-50",
                "type": "text",
            },
            {
                "name": "course_name",
                "selector": ".text-block-93",
                "type": "text",
            },
            {
                "name": "course_icon",
                "selector": ".image-92",
                "type": "attribute",
                "attribute": "src"
            }
        ]
    }

    extraction_strategy = JsonCssExtractionStrategy(schema, verbose=True)

    browser_config = BrowserConfig(headless=False, verbose=True)
    run_config = CrawlerRunConfig(
        extraction_strategy=extraction_strategy,
        js_code=["""(async () => {
            const tabs = document.querySelectorAll("section.charge-methodology .tabs-menu-3 > div");
            for(let tab of tabs) {
                tab.scrollIntoView();
                tab.click();
                await new Promise(r => setTimeout(r, 500));
            }
        })();"""],
        cache_mode=CacheMode.BYPASS
    )
        
    async with AsyncWebCrawler(config=browser_config) as crawler:
        result = await crawler.arun(
            url="https://www.example.com/degrees/technology",
            config=run_config
        )

        companies = json.loads(result.extracted_content)
        print(f"成功提取 {len(companies)} 条数据")
        print(json.dumps(companies[0], indent=2))

if __name__ == "__main__":
    asyncio.run(main())

4.2.2 使用 LLM 提取结构化数据

import os
import asyncio
from crawl4ai import AsyncWebCrawler, BrowserConfig, CrawlerRunConfig, LLMConfig
from crawl4ai import LLMExtractionStrategy
from pydantic import BaseModel, Field

class OpenAIModelFee(BaseModel):
    model_name: str = Field(..., description="OpenAI 模型名称")
    input_fee: str = Field(..., description="输入 Token 费用")
    output_fee: str = Field(..., description="输出 Token 费用")

async def main():
    browser_config = BrowserConfig(verbose=True)
    run_config = CrawlerRunConfig(
        word_count_threshold=1,
        extraction_strategy=LLMExtractionStrategy(
            llm_config=LLMConfig(
                provider="openai/gpt-4o",
                api_token=os.getenv('OPENAI_API_KEY')
            ),
            schema=OpenAIModelFee.schema(),
            extraction_type="schema",
            instruction="""从爬取的内容中,提取所有提到的模型名称及其输入输出 Token 费用。
            不要遗漏内容中的任何模型。提取的 JSON 格式示例:
            {"model_name": "GPT-4", "input_fee": "US$10.00 / 1M tokens", "output_fee": "US$30.00 / 1M tokens"}。"""
        ),            
        cache_mode=CacheMode.BYPASS,
    )
    
    async with AsyncWebCrawler(config=browser_config) as crawler:
        result = await crawler.arun(
            url='https://openai.com/api/pricing/',
            config=run_config
        )
        print(result.extracted_content)

if __name__ == "__main__":
    asyncio.run(main())

4.3 实际项目示例

示例:构建 RAG 系统的数据管道

import asyncio
from crawl4ai import AsyncWebCrawler, BrowserConfig, CrawlerRunConfig
from crawl4ai.deep_crawling import BFSDeepCrawlStrategy

async def build_rag_dataset():
    """为 RAG 系统构建数据集"""
    browser_config = BrowserConfig(headless=True, verbose=False)
    
    # 配置深度爬取
    deep_crawl = BFSDeepCrawlStrategy(
        max_depth=2,
        max_pages=50,
        include_external=False
    )
    
    run_config = CrawlerRunConfig(
        deep_crawl_strategy=deep_crawl,
        markdown_generator=DefaultMarkdownGenerator(
            content_filter=PruningContentFilter(threshold=0.5)
        ),
        cache_mode=CacheMode.ENABLED  # 启用缓存加速
    )
    
    async with AsyncWebCrawler(config=browser_config) as crawler:
        result = await crawler.arun(
            url="https://docs.example.com",
            config=run_config
        )
        
        # 保存所有页面的 Fit Markdown
        for i, (url, markdown) in enumerate(zip(
            result.deep_crawl_results['urls'],
            result.deep_crawl_results['markdown']
        )):
            with open(f"rag_data/page_{i}.md", "w") as f:
                f.write(f"# {url}\n\n{markdown}")

if __name__ == "__main__":
    asyncio.run(build_rag_dataset())

五、常见问题与解决方案

5.1 安装失败

问题pip install crawl4ai 后运行 crawl4ai-setup 失败。

解决方案

  1. 手动安装 Playwright 浏览器:
    python -m playwright install chromium
    
  2. 如果使用 macOS,可能需要安装依赖:

5.2 运行时错误

问题Error: Executable doesn't exist at ...

解决方案

# 重新安装 Playwright 浏览器
playwright install --force chromium

问题asyncio.exceptions.TimeoutError

解决方案

  • 增加超时时间:
    run_config = CrawlerRunConfig(
        page_timeout=60000,  # 60 秒
        cache_mode=CacheMode.BYPASS
    )
    
  • 使用 headless=False 观察浏览器行为

5.3 性能问题

问题:爬取速度慢

解决方案

  1. 启用缓存:
    run_config = CrawlerRunConfig(
        cache_mode=CacheMode.ENABLED
    )
    
  2. 使用 prefetch=True 模式快速发现 URL:
    run_config = CrawlerRunConfig(prefetch=True)
    
  3. 调整浏览器池大小(Docker 部署时):
    docker run -d -p 11235:11235 \
      -e CRAWL4AI_BROWSER_POOL_SIZE=10 \
      --name crawl4ai \
      unclecode/crawl4ai:latest
    

5.4 兼容性

问题:某些网站无法正确渲染

解决方案

  1. 启用 magic=True 自动处理常见反爬措施:
    result = await crawler.arun(url, magic=True)
    
  2. 使用 undetected Chrome 模式:
    browser_config = BrowserConfig(
        browser_type="undetected",
        headless=True
    )
    
  3. 配置代理链和重试策略(v0.8.5+):
    from crawl4ai.async_configs import ProxyConfig
    
    run_config = CrawlerRunConfig(
        proxy_config=[
            ProxyConfig.DIRECT,
            ProxyConfig(server="http://my-proxy:8080")
        ],
        max_retries=2
    )
    

六、总结

Crawl4AI 是一款功能强大且易于使用的开源 Web 爬虫工具,特别适合需要将网页内容转换为 LLM 友好格式的场景。其核心优势包括:

  1. 专为 LLM 优化:生成的 Markdown 格式天然适合 RAG 和 AI Agent
  2. 灵活的配置:支持从简单爬取到复杂的深度爬取和结构化提取
  3. 活跃的社区:50,000+ Star,持续的版本更新和问题修复
  4. 多种部署方式:支持 Python API、CLI、Docker、云部署

无论是构建 RAG 系统、训练数据集,还是开发 AI Agent,Crawl4AI 都能显著简化数据获取和预处理流程。

相关资源

  • 官方文档:https://docs.crawl4ai.com/
  • GitHub 仓库:https://github.com/unclecode/crawl4ai
  • Docker 镜像unclecode/crawl4ai:latest
  • 赞助支持:https://github.com/sponsors/unclecode

标签:#Crawl4AI #Web爬虫 #LLM #RAG #开源工具 #Python #数据抓取