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

推荐订阅源

L
LangChain Blog
The GitHub Blog
The GitHub Blog
Recent Announcements
Recent Announcements
MyScale Blog
MyScale Blog
P
Proofpoint News Feed
S
Security @ Cisco Blogs
N
News and Events Feed by Topic
H
Hacker News: Front Page
Attack and Defense Labs
Attack and Defense Labs
S
Secure Thoughts
Microsoft Security Blog
Microsoft Security Blog
N
Netflix TechBlog - Medium
U
Unit 42
Stack Overflow Blog
Stack Overflow Blog
T
Threat Research - Cisco Blogs
Google Online Security Blog
Google Online Security Blog
Spread Privacy
Spread Privacy
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
L
LINUX DO - 热门话题
T
Tenable Blog
博客园 - 叶小钗
D
DataBreaches.Net
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
博客园_首页
人人都是产品经理
人人都是产品经理
aimingoo的专栏
aimingoo的专栏
C
Check Point Blog
博客园 - 三生石上(FineUI控件)
量子位
P
Proofpoint News Feed
H
Help Net Security
Blog — PlanetScale
Blog — PlanetScale
宝玉的分享
宝玉的分享
Recorded Future
Recorded Future
The Register - Security
The Register - Security
F
Fortinet All Blogs
Engineering at Meta
Engineering at Meta
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Last Week in AI
Last Week in AI
S
Schneier on Security
V
Vulnerabilities – Threatpost
雷峰网
雷峰网
Microsoft Azure Blog
Microsoft Azure Blog
G
GRAHAM CLULEY
G
Google Developers Blog
月光博客
月光博客
V
V2EX
T
Troy Hunt's Blog
A
Arctic Wolf

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号基地 删除右键“打开方式”里多余选项 第三周刊_No.53|一切都会被支付两次 安卓APP通话记录与录音上传踩坑记录 - 子舒的博客 天量下跌 inBox 笔记 2.3.8,把工具栏交给了你-咕咚同学 我把小龙虾搬到了微信-咕咚同学 安好 - 响石潭 Compound Engineering Plugin:让每个工程单元都比上一个更容易 MOSS-TTS Family:开源高质量语音与声音生成模型家族深度解析 Build Your Own X:从零实现你最喜欢的技术——程序员进阶的终极资源清单 Anthropic Skills:用文件夹教 Claude 专业技能的开源框架 1年的去月球(下) - 梅之夏 欢迎回来。 简单讲讲 ASN.1 与 OID DTV - 直播聚合客户端 5.22-5.27 – 不兴江 还没去过鸭川 – 不兴江 张晶晶同学三刷林志颖 关于我 – 不兴江 爱与嫉妒 – 不兴江 港股被持续做空 备案码花了四百块-咕咚同学 一句话生成封面:我给公众号做了4种风格的AI封面生成技能 「官」方認證 再谈费曼学习法 2026-05-28T00:34:11+08:00 2026-05-28T00:28:45+08:00 离谱的英语学习指南:基于AI的英语进阶系统方法论 iii:零集成架构的后端统一运行时 Claude Code Harness:让 Claude Code 工作有迹可循的工程化框架 Heretic:全自动移除大语言模型审查机制的开源工具 MarkItDown:微软开源的万能文档转 Markdown 利器 Harness:让 Claude Code 秒变多智能体协作工厂 这段时间尽折腾AI Agent了,确实极大地提高了效率 近期动态:两个新站点正式上线啦 误判解除!zhouayuan.com 腾讯安全申诉成功 - 周阿源|玩具设计・插画日常・生活随笔 Ralph:让 AI 编码工具自主循环跑完所有 PRD 任务的量产神器 全都违法 – 个人工作记录 关于zhouayuan.com被误判 “含违规信息” 的说明与申诉记录 - 周阿源|玩具设计・插画日常・生活随笔 小米 MiMo v2.5 Pro 白嫖 最大的人间清醒,兜里有钱,但是不花。 夜晚靓歌(12):于文文现场solo - 王志勇的Blog 今日插画:风扬起的倔强 - 周阿源|玩具设计・插画日常・生活随笔 回门习俗 独立网卡 - 忘记了回忆 500亿入股人工智能企业 从命令行到桌面智能体-咕咚同学 第一性原理读书笔记 行者微评论223-加班の守株待兔-博客|政治与时事-风雨行者 ZOZO开源物理接触求解器:GPU加速的可扩展仿真引擎 OpenStock:开源股票市场交易平台技术深度解析 MoneyPrinterTurbo:基于AI的全自动短视频生成工具深度解析 Claude-Mem:为 Claude Code 构建的持久化记忆压缩系统 Twenty:可代码化定制的企业级开源 CRM 平台技术深度解析 2026-05-26T22:59:17+08:00 企业级开源大模型部署平台 GPUStack 实战教程 1年的去月球(上) - 梅之夏 Sevalla - 静态网站托管服务 不用翻墙、不用注册、不用月费,普通人也能用上 Claude Code 装修灯具要注意⚠️ 黄梅天先锋 - 游子微博 公安备案顺利办结,站点备案全部完成 - 周阿源|玩具设计・插画日常・生活随笔 第三次兑换天猫超市卡了宗宗酱-三维狐少儿编程 Don't think, feel. - Rolen's Blog 人这一辈子,到底图个什么 博客迁移 - Edwin's Blog 情感赛道写作模板 再现本轮行情的典型特征 裁员与平常心-咕咚同学 别让“偷懒”,成为隐私泄露的破绽 片刻 - Jdeal | Life is like a Design.
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 #数据抓取