第 3 课

深度爬取、批量抓取、截图导出与命令行;MCP 与 LLM 提取怎么接

用 BFSDeepCrawlStrategy 从官方安装文档做一层深度爬取并读 metadata.depth;用 arun_many 并发抓多个 URL;打开 screenshot 与 pdf 导出;用 crwl 命令行复现;LLMExtractionStrategy 与 Docker / Cloud MCP 按官方说明整理并标

图文20 分钟Crawl4AI 官方文档 ↗

课程目录第 3 / 3 课

学习位置仅保存在当前浏览器,有效期 180 天。

01 / 图文教材

图文教材

本课对照的官方页面:Quick Start(Adaptive / Multi-URL) 、CLI 、Self-Hosting / MCP 。测试环境同前两课。深度爬取、arun_many、截图 / PDF、crwl 均已实测;LLMExtractionStrategy、Docker 自建 MCP、Cloud 远程 MCP 测试机没有 API Key 或 Docker,按官方说明整理并标注「未实测」。

前两课处理的是「一个 URL」。这一课往外扩一层:顺着站内链接爬一层、一次丢多个 URL、把页面存成截图或 PDF,再用命令行把同样的事做一遍。最后说明怎样接到大模型提取和 MCP(这两块本课未实测)。

第 1 步:BFS 深度爬取(限制页数)

BFSDeepCrawlStrategy 从起始页出发,按广度优先跟随站内链接。务必加上 max_depth 和 max_pages,否则很容易爬爆。新建 deep_crawl.py:

import asyncio
from crawl4ai import (
    AsyncWebCrawler,
    BrowserConfig,
    CrawlerRunConfig,
    CacheMode,
    BFSDeepCrawlStrategy,
)

async def main():
    deep = BFSDeepCrawlStrategy(
        max_depth=1,
        include_external=False,
        max_pages=5,
    )
    run = CrawlerRunConfig(
        cache_mode=CacheMode.BYPASS,
        deep_crawl_strategy=deep,
        stream=True,
    )
    start = "https://docs.crawl4ai.com/core/installation/"
    async with AsyncWebCrawler(config=BrowserConfig(headless=True)) as crawler:
        async for result in await crawler.arun(start, config=run):
            md = result.markdown.raw_markdown
            meta = result.metadata or {}
            print(
                f"OK depth={meta.get('depth')} "
                f"md_len={len(md)} url={result.url}"
            )

asyncio.run(main())

对照结果(本机 2026-11-06):

OK depth=0 md_len=13872 url=https://docs.crawl4ai.com/core/installation/
OK depth=1 md_len=16647 url=https://docs.crawl4ai.com/
OK depth=1 md_len=6658 url=https://docs.crawl4ai.com/core/ask-ai/
OK depth=1 md_len=7760 url=https://docs.crawl4ai.com/stats/

读法:

  • depth=0 是起始页;depth=1 是从起始页链出去、且仍在同站的页面。
  • include_external=False 不跟外链。
  • stream=True 时用 async for 边爬边处理;也可以设 stream=False 一次拿列表。
  • result.metadata 里还有 title、parent_url 等字段,做知识库时可以把父子关系记下来。

同一件事也可以用命令行(输出会把多页 Markdown 拼在一起,适合快速摸底):

crwl crawl "https://docs.crawl4ai.com/core/installation/" \
  --deep-crawl bfs --max-pages 3 -o markdown -bc | head -n 3

对照结果(开头):

============================================================
# https://docs.crawl4ai.com/core/installation/
============================================================

第 2 步:arun_many 批量抓多个 URL

URL 列表已知、彼此独立时,不必走深度策略,直接 arun_many:

import asyncio
from crawl4ai import AsyncWebCrawler, BrowserConfig, CrawlerRunConfig, CacheMode

async def main():
    urls = [
        "https://example.com",
        "https://docs.crawl4ai.com/core/quickstart/",
        "https://docs.crawl4ai.com/core/installation/",
    ]
    run = CrawlerRunConfig(cache_mode=CacheMode.BYPASS, stream=False)
    async with AsyncWebCrawler(config=BrowserConfig(headless=True)) as crawler:
        results = await crawler.arun_many(urls, config=run)
        for r in results:
            n = len(r.markdown.raw_markdown) if r.success else 0
            flag = "OK" if r.success else "ERR"
            print(f"[{flag}] md_len={n} url={r.url}")

asyncio.run(main())

对照结果:

[OK] md_len=953 url=https://example.com
[OK] md_len=26239 url=https://docs.crawl4ai.com/core/quickstart/
[OK] md_len=13945 url=https://docs.crawl4ai.com/core/installation/

默认调度器会按机器内存自适应并发。若要边完成边处理,把 stream=True,再写成 async for result in await crawler.arun_many(...)。

第 3 步:导出截图和 PDF

在 CrawlerRunConfig 里打开 screenshot=True 和 pdf=True。返回值里的 result.screenshot / result.pdf 通常是 Base64 字符串,解码后写入文件:

import asyncio
import base64
from pathlib import Path
from crawl4ai import AsyncWebCrawler, BrowserConfig, CrawlerRunConfig, CacheMode

async def main():
    run = CrawlerRunConfig(
        cache_mode=CacheMode.BYPASS,
        screenshot=True,
        pdf=True,
    )
    out = Path("exports")
    out.mkdir(exist_ok=True)
    async with AsyncWebCrawler(config=BrowserConfig(headless=True)) as crawler:
        r = await crawler.arun("https://example.com", config=run)
        print("success", r.success)
        print("screenshot_present", bool(r.screenshot))
        print("pdf_present", bool(r.pdf))
        if r.screenshot:
            data = base64.b64decode(r.screenshot)
            (out / "example.png").write_bytes(data)
            print("screenshot_bytes", len(data))
        if r.pdf:
            data = base64.b64decode(r.pdf)
            (out / "example.pdf").write_bytes(data)
            print("pdf_bytes", len(data))

asyncio.run(main())

对照结果:

success True
screenshot_present True
pdf_present True
screenshot_bytes 58195
pdf_bytes 112742

本机截图约 58 KB(1080×600),PDF 约 113 KB。做验收报告或给人工复核页面时,这两种导出很方便;crawl4ai-doctor 在健康检查里也会顺带测导出链路。

第 4 步:命令行常用组合

把前几课的动作收成几条 CLI(均在已激活的虚拟环境里):

# 只要 Markdown
crwl crawl https://example.com -o markdown -bc

# 写入文件
crwl crawl https://example.com -o markdown -O example.md -bc

# 深度爬取,最多 3 页,输出完整结果 JSON
crwl crawl "https://docs.crawl4ai.com/core/installation/" \
  --deep-crawl bfs --max-pages 3 -o all -bc > deep.json

本课实测:example.md 大小 1337 字节;deep.json 解析后是一个数组,例如 3 页时每项带 url、success、markdown 等字段。-o json 只在你启用了提取策略(-e / -j)时才有「抽出的结构化数据」;平时看全文用 markdown 或 all。

第 5 步:LLMExtractionStrategy(未实测)

页面结构乱七八糟、或字段要靠语义判断时,官方提供 LLMExtractionStrategy:你给一个 Pydantic / JSON schema 和一段 instruction,由大模型把正文填进结构。Quick Start 示例大致是:

from crawl4ai import LLMConfig, LLMExtractionStrategy, CrawlerRunConfig, CacheMode

run = CrawlerRunConfig(
    cache_mode=CacheMode.BYPASS,
    extraction_strategy=LLMExtractionStrategy(
        llm_config=LLMConfig(
            provider="openai/gpt-4o",
            api_token="YOUR_KEY",
        ),
        schema=YourModel.model_json_schema(),
        extraction_type="schema",
        instruction="Extract all items mentioned in the page.",
    ),
)

也可以把 provider 换成 ollama/llama3.3 之类本机模型(通常不需要云端 token)。本课测试机没有可用的云端 API Key,也没有常驻的 Ollama 服务,所以这一步未实测。接好密钥后,把 arun 的 URL 换成目标页,打印 result.extracted_content 即可验证。

第 6 步:Docker 自建 MCP 与 Cloud MCP(未实测)

官方 Self-Hosting 文档说明:用 Docker 跑 Crawl4AI 服务后,可在 http://localhost:11235 提供 HTTP API,并带 MCP 端点,供 Claude Code 等客户端把「抓网页 / 截图 / 执行 JS」当成工具来调。Cloud 托管版则提供远程 MCP:https://api.crawl4ai.com/mcp(需要 API Key)。

本课测试机没有拉取官方镜像,也没有 Cloud Key,因此 Docker MCP 与 Cloud MCP 均未实测。你若已有 Docker,可按 https://docs.crawl4ai.com/core/self-hosting/ 先 curl http://localhost:11235/health 确认服务起来,再在 MCP 客户端里填文档给出的 SSE / WebSocket 地址。本地 Python 库本身已经能完成前四步的抓取;MCP 是「把同一能力交给智能体客户端」的部署方式,不是写业务脚本的前提。

小结

  • 深度爬取用 BFSDeepCrawlStrategy,务必限制 max_depth / max_pages;用 metadata.depth 判断层级。
  • 已知 URL 列表时用 arun_many;需要边完成边处理就开 stream=True。
  • screenshot=True / pdf=True 后从结果里 Base64 解码落盘。
  • 命令行 crwl crawl 加输出格式与深度爬取参数,适合快速摸底。
  • 大模型提取与 MCP 接入按官方文档配置密钥或 Docker;本课未实测这两块。