第 3 课
深度爬取、批量抓取、截图导出与命令行;MCP 与 LLM 提取怎么接
用 BFSDeepCrawlStrategy 从官方安装文档做一层深度爬取并读 metadata.depth;用 arun_many 并发抓多个 URL;打开 screenshot 与 pdf 导出;用 crwl 命令行复现;LLMExtractionStrategy 与 Docker / Cloud MCP 按官方说明整理并标
课程目录第 3 / 3 课
学习位置仅保存在当前浏览器,有效期 180 天。
图文教材
本课对照的官方页面: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;本课未实测这两块。
