Crawl4AI 实战指南:网页采集从登录页到结构化 JSON 的 3 个关键能力
2026/8/29 22:45:14 网站建设 项目流程

Crawl4AI 实战指南:网页采集从登录页到结构化 JSON 的 3 个关键能力

【免费下载链接】crawl4ai🚀🤖 Crawl4AI: Open-source LLM Friendly Web Crawler & Scraper. Don't be shy, join here: https://discord.gg/jP8KfhDhyN项目地址: https://gitcode.com/GitHub_Trending/craw/crawl4ai

凌晨三点,定时任务报警:你的爬虫又挂在登录页上了。登录态是三天前存的 Cookie,站点那边一次风控升级,全作废了。换个目标站更糟——页面只抓到一半,剩下 70% 的内容要靠"加载更多"点出来;好不容易抓到整页 HTML,解析脚本又因为对方改了一处 class 名直接崩掉。这三个问题——登录态、动态内容、结构化提取——基本是每个做网页采集的人都绕不开的。Crawl4AI 是一个基于 Playwright 的开源 LLM 友好型爬虫,把这三件事做成了开箱即用的能力。读完这篇,你会知道它分别是怎么做的,以及哪些坑别踩。

快速上手:装好、装浏览器、跑第一条命令

pip install crawl4ai crawl4ai-setup # 下载 Playwright 浏览器,首次必做 # 抓一个页面,输出 Markdown crwl crawl https://example.com -o markdown

输出就是一段干净的 Markdown 正文,导航栏、页脚、广告这些噪音默认被过滤掉,可以直接喂给下游程序或 LLM。想先跑通 Python 侧,最小形态是:

from crawl4ai import AsyncWebCrawler, BrowserConfig, CrawlerRunConfig import asyncio async def main(): async with AsyncWebCrawler(config=BrowserConfig(headless=True)) as crawler: r = await crawler.arun("https://example.com", config=CrawlerRunConfig()) print(r.markdown.raw_markdown[:200]) # 前 200 字符预览 asyncio.run(main())

基础爬取:一条命令拿到干净的 Markdown,是后面所有能力的地基

登录一次,跑一百次:Profile 管理登录态

它解决什么问题

最典型的翻车现场:你爬的是一个需要登录的后台,代码里存了一堆 Cookie,结果这周还好好的,下周全部 401。只存凭据不存"人",站点随时能发现你不是真人。

原理一句话

Profile 不是存 Cookie,而是持久化一整个用户浏览器数据目录:Cookie、localStorage、缓存、UA 指纹都在里面。创建 profile 时它会弹出一个真实浏览器窗口,你像正常人一样把登录流程走一遍(短信码、二次验证都行),按q保存;之后每次爬取,Crawl4AI 都用这份目录起浏览器,对站点来说你就是那个已经登录过的老用户。

动手试

# 交互式创建:弹出浏览器,完成登录后按 q 保存 crwl profiles create bank-auth # 确认已保存的 profile crwl profiles list # 带着 profile 爬受保护页面 crwl crawl https://bank-portal.com/statements -p bank-auth -o json # 确认不再需要时删除 crwl profiles delete bank-auth

想直接在 Python 里复用,就是给BrowserConfig指个数据目录:

config = BrowserConfig(headless=True, user_data_dir="~/.crawl4ai/profiles/bank-auth")

坑与注意事项

  • Cookie 会过期。过期后表现是爬回来的是登录页而不是数据页,重新跑一次crwl profiles create把流程走完即可,不用改任何代码。
  • Profile 里是明文的会话凭据,别提交进代码仓库,也别在共享机器上留给你没打算公开身份的 profile。

登录态解决了,下一个麻烦是页面本身:很多站的内容要等 JS 执行完、甚至要滚动触发之后才出现。

让页面自己滚动到加载完:动态内容与等待策略

它解决什么问题

"为什么我的输出只有第一屏?"因为默认行为是等页面加载完成就取 HTML,而懒加载、无限滚动、异步填充的内容根本还没开始加载。time.sleep(5)是最常见的自救方式,但 5 秒对长列表不够,对短页面又白白浪费时间,等于用时间换不确定性。

原理一句话

Crawl4AI 把"取 HTML 的时机"拆成了几个可配置的开关:wait_until="networkidle"等网络请求静默、wait_for轮询某个 CSS 选择器出现、delay_before_return_html给 JS 留最后一点时间。配合全页扫描时自动逐步滚动(scroll_delay控制步长间隔、max_scroll_steps控制总步数),列表就能被一页一页"滚"出来。

动手试

crwl crawl https://some-site.com/products \ -c "wait_until=networkidle, # 等网络请求静默 max_scroll_steps=8, # 全页扫描最多滚 8 步 scroll_delay=0.5, # 每步滚动后留 0.5 秒加载 wait_for=.card, # 确保至少一张卡片已渲染 css_selector=main, # 只取 <main> 内的内容" \ -o markdown

动态页面:等待、滚动、元素检测组合起来,页面加载到什么程度再取 HTML 由你定

坑与注意事项

  • 虚拟列表(Twitter、Instagram 这类)只渲染可视区域,滚走的内容会被回收,普通滚动会漏数据。这类页面用专门的VirtualScrollConfig,官方有个带本地模拟站的完整示例:docs/examples/virtual_scroll_example.py
  • 别为了"保险"把delay_before_return_html调到 3 秒以上。wait_until=networkidlewait_for已经覆盖了绝大多数场景,固定长延迟只会拖慢整体吞吐。

内容抓全了,下一个问题:下游要的是字段化的 JSON,不是 Markdown。

CSS 与 LLM 双通道:把页面变成 JSON

它解决什么问题

用正则去切 HTML 是维护噩梦:前端换一次 class,你的解析脚本就崩一次。而"全交给 LLM"也不现实——慢、贵、结构不稳定的输出还要二次清洗。

原理一句话

Crawl4AI 把提取做成了可插拔的策略:JsonCssExtractionStrategy拿一份 JSON schema(baseSelector + 字段级选择器)精确取字段,零 LLM 成本;LLMExtractionStrategy拿一段自然语言指令 + 可选 schema 让大模型理解页面语义,适合改版频繁的结构;两个策略可以同时挂在一次爬取里,哪个稳用哪个。

动手试

CSS 通道:先写一份 schema 文件(这里对应docs/examples/cli/css_schema.json的格式):

{ "name": "ArticleExtractor", "baseSelector": ".card", "fields": [ { "name": "title", "selector": "h4.card__title", "type": "text" }, { "name": "link", "selector": "h4.card__title a", "type": "attribute", "attribute": "href" } ] }
# 结构化提取:schema 定字段,直接出 JSON crwl crawl https://some-site.com/news \ -e extract_css.yml \ -s docs/examples/cli/css_schema.json \ -o json

输出就是[{ "title": "...", "link": "..." }, ...]这样的数组。

CSS 提取通道:schema 写一次,字段稳定可预期,适合结构固定的站点

LLM 通道一行就能起:

# -j 后跟自然语言指令,不跟则用默认指令 crwl crawl https://some-site.com/blog/latest \ -j "提取文章标题、发布日期、作者,按时间倒序,排除广告" \ -o json

LLM 提取依赖llm_config.yml里配置的 provider 和 API key,首次使用先配好再跑。

LLM 提取通道:自然语言指令直接换结构化字段,适合结构多变或语义复杂的页面

坑与注意事项

  • 结构稳定的站点优先用 CSS 通道,快、可预期、零 token 成本;LLM 通道留给那些"每次改版都得改选择器"的站。
  • 用 LLM 提取时尽量传schema强制输出结构,否则字段名和嵌套层级可能逐次漂移,下游对不齐。

同一个功能,CLI 和 Python 是两种姿态,选错会难受。

三种用法怎么选:CLI、Python API、还是混着来

用法适合什么
CLI 单条命令一次性抓页面、定时任务、CI 脚本;给个 URL 就出 markdown/JSON
Python API采集逻辑进业务代码:复用浏览器上下文、多 URL 并发、带交互、带回调
混合先用 CLI 快速验证选择器和 LLM 指令,跑通后原样搬进 Python 项目

什么时候该用它,什么时候别用:目标站是纯静态 HTML 的话,requests加一个 HTML 解析库就够了,没必要拉一个浏览器起来;需要登录、等 JS、滚动加载、稳定出 JSON 字段时,Crawl4AI 基本能覆盖;但它本质是单机异步工具,不是任务队列——大规模分布式采集要自己在外面再包一层调度。

完整工作流:把整个 API 文档站镜像成本地 Markdown

背景:把某开源项目的文档站(API 参考部分,几十个子页)拉到本地存档,列表页里全是子页链接,单页无登录。

配置BfsStrategy控制爬取深度,include_patterns限定只进/docs/api/前缀,CSS 提取器每页取标题和正文。

import asyncio from pathlib import Path from crawl4ai import AsyncWebCrawler, BrowserConfig, CrawlerRunConfig from crawl4ai import BfsStrategy, JsonCssExtractionStrategy SCHEMA = { # 与前面 CSS 通道同一套 schema 格式 "name": "DocPage", "baseSelector": "main", "fields": [ {"name": "title", "selector": "h1", "type": "text"}, {"name": "body", "selector": "article", "type": "html"} ], } async def main(): async with AsyncWebCrawler(config=BrowserConfig(headless=True)) as crawler: config = CrawlerRunConfig( deep_crawl_strategy=BfsStrategy(max_depth=2), # 只下钻 2 层 include_patterns=["*/docs/api/*"], # 限定 API 前缀 extraction_strategy=JsonCssExtractionStrategy(SCHEMA), ) results = await crawler.arun_many(["https://docs.example.com/docs/api/"], config=config) out = Path("mirror"); out.mkdir(exist_ok=True) for r in results: if r.extracted_content: (out / (r.url.split("/")[-1] + ".json")).write_text(r.extracted_content) print(f"done: {len(results)} pages") asyncio.run(main())

产出mirror/目录下每页一个 JSON,标题和正文已按 schema 对齐,可以直接进知识库或向量库。

收尾

回到开头那三个场景:登录态失效,现在存成一个 profile,过期了重走一次流程;页面只抓一半,交给滚动和等待策略;解析脚本天天崩,换成 CSS schema 或 LLM 指令。工具没变多,麻烦少了一大半。

  • 文档总入口:docs/
  • 虚拟滚动、CSS 与 LLM 提取的完整示例:docs/examples/
  • 深度爬取策略说明:docs/md_v2/core/deep-crawling.md

【免费下载链接】crawl4ai🚀🤖 Crawl4AI: Open-source LLM Friendly Web Crawler & Scraper. Don't be shy, join here: https://discord.gg/jP8KfhDhyN项目地址: https://gitcode.com/GitHub_Trending/craw/crawl4ai

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询