news 2026/8/29 15:24:42

Crawl4AI 实战手册:从安装到并发爬取、动态页面与结构化提取的完整路径

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Crawl4AI 实战手册:从安装到并发爬取、动态页面与结构化提取的完整路径

Crawl4AI 实战手册:从安装到并发爬取、动态页面与结构化提取的完整路径

【免费下载链接】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

凌晨两点,你把一段 30 万字符的 HTML 原样丢给大模型,它回给你的答案却淹没在导航栏、广告位和页脚版权信息里;而一个同步爬虫卡在某个 JS 渲染的页面上,后面排队的 50 个 URL 全部干等。Crawl4AI 是一个开源的 LLM 友好型异步爬虫框架,把"浏览器渲染 → 内容清洗 → Markdown/结构化输出"这条链路压缩成几次 API 调用,这篇文章带你装好它、跑通基础案例,并把动态页面、并发控制和结构化提取这三块能力拆解到位。

它到底能帮你解决什么

🔍页面噪声拖垮 LLM 输入质量:原始 Markdown 把页面上的每个角落都翻译进去了。Crawl4AI 内置内容过滤器,fit_markdown会给你一份剪掉导航、页脚后的干净正文,直接可喂给模型。

串行爬取慢得没法上生产arun_many基于异步 IO 并发处理一批 URL,默认按可用内存自适应调节并发度,还能流式返回结果。

🕹️JS 渲染的页面抓回来是空壳:通过js_code注入脚本、wait_for等待条件、extraction_strategy输出 JSON 三个参数组合,动态站点和结构化数据都能拿到。

五分钟跑通第一个可运行案例

安装和浏览器内核准备各占一行,跑完crawl4ai-doctor无报错就可以开爬:

pip install -U crawl4ai crawl4ai-setup crawl4ai-doctor

下面是最小可运行示例,一次arun调用拿到清洗后的 Markdown:

import asyncio from crawl4ai import AsyncWebCrawler async def main(): async with AsyncWebCrawler() as crawler: # 自动启动无头 Chromium result = await crawler.arun("https://example.com") print(result.markdown[:300]) # raw_markdown:HTML 转 Markdown 的完整结果 if __name__ == "__main__": asyncio.run(main())

跑完你会在控制台看到 example.com 页面的 Markdown 开头部分——没有 requests 里那种<script>标签堆砌,这就是"LLM 友好"的第一层含义。

核心能力一:Markdown 输出的两种粒度怎么切换

解决的问题:result.markdown其实存了两份内容,用错了粒度,要么 LLM token 白白烧在导航上,要么解析时又丢了细节。

import asyncio from crawl4ai import AsyncWebCrawler, CrawlerRunConfig, CacheMode from crawl4ai import DefaultMarkdownGenerator from crawl4ai.content_filter_strategy import PruningContentFilter async def main(): config = CrawlerRunConfig( cache_mode=CacheMode.BYPASS, # 默认即 BYPASS,这里显式声明 markdown_generator=DefaultMarkdownGenerator( content_filter=PruningContentFilter(threshold=0.4, threshold_type="fixed") ), ) async with AsyncWebCrawler() as crawler: result = await crawler.arun("https://news.ycombinator.com", config=config) print(len(result.markdown.raw_markdown)) # 全量转换,约 6 万字符 print(len(result.markdown.fit_markdown)) # 剪枝后,只剩正文主体 if __name__ == "__main__": asyncio.run(main())

关键参数:raw_markdown是无过滤的完整转换结果,适合做存档和二次解析;fit_markdown是经过PruningContentFilter剪枝后的版本,threshold=0.4表示保留相关性得分前 40% 的文本块,这是喂给 LLM 的推荐粒度。过滤器会增加约 50ms 处理时间,换来的是 token 成本下降一个量级。

核心能力二:JS 渲染页面的脚本注入与等待怎么配

解决的问题:内容靠按钮点击或异步请求加载的页面,直接提取只能拿到骨架。

import asyncio from crawl4ai import AsyncWebCrawler, BrowserConfig, CrawlerRunConfig, CacheMode js_load_more = """ (async () => { const btn = [...document.querySelectorAll('button')] .find(b => b.textContent.includes('Load More')); if (btn) { btn.click(); } // 触发"加载更多"的异步加载 })(); """ async def main(): config = CrawlerRunConfig( cache_mode=CacheMode.BYPASS, js_code=[js_load_more], # 页面加载完成后注入执行 wait_for=3000, # 给异步请求留足时间再提取 page_timeout=60000, ) async with AsyncWebCrawler(config=BrowserConfig(headless=False)) as crawler: result = await crawler.arun("https://example.com/feed", config=config) print(result.markdown.raw_markdown[:300]) if __name__ == "__main__": asyncio.run(main())

js_code接收字符串列表,每条都会在页面就绪后执行;wait_for可以是超时毫秒数或 CSS 选择器,选择器形式会等到元素出现才提取,比死等更稳。本地调试时把headless=False打开,能直接看到脚本点击的过程,排查选择器问题时非常直观。

核心能力三:并发爬取的流式结果与信号量怎么调

解决的问题:要一次抓几十个页面,串行跑要等最慢的那个,还容易把浏览器内存撑爆。

import asyncio from crawl4ai import AsyncWebCrawler, CrawlerRunConfig, CacheMode urls = [ "https://example.com/page1", "https://example.com/page2", "https://example.com/page3", ] async def main(): config = CrawlerRunConfig( cache_mode=CacheMode.BYPASS, stream=True, # 边完成边产出,不等全部结束 semaphore_count=8, # 最多同时 8 个页面在跑 ) async with AsyncWebCrawler() as crawler: async for result in await crawler.arun_many(urls, config=config): if result.success: print(f"[OK] {result.url},{len(result.markdown.raw_markdown)} 字符") else: print(f"[ERR] {result.url} => {result.error_message}") if __name__ == "__main__": asyncio.run(main())

默认调度器会按系统可用内存自适应调节并发度;stream=True让结果在各自完成时立刻产出,适合接后续入库或 LLM 处理。单个 URL 失败不会中断整批,success标志位配合error_message足够你做重试逻辑。

组合拳——实际项目里怎么搭配用

场景 A:登录态下的多步操作。先访问登录页,再带着同一session_id抓后台页面,后续步骤用js_only=True避免重复导航,最后kill_session()清理:

result1 = await crawler.arun( url="https://example.com/login", session_id="my_session", # 建立会话,Cookie/Storage 都会保留 ) result2 = await crawler.arun( url="https://example.com/dashboard", session_id="my_session", # 复用同一浏览器上下文 js_only=True, # 只执行 JS,不重新加载页面 ) await crawler.kill_session("my_session") # 用完即释放

适合电商后台、需要翻页点击的报表页等"一个页面状态要带到下一个动作"的流程。

场景 B:CSS 定位 + JSON 提取一次到位。css_selector把抓取范围锁死在列表区,extraction_strategy直接吐出结构化数据,全程不花 LLM 的钱:

from crawl4ai import JsonCssExtractionStrategy schema = { "name": "Items", "baseSelector": "div.item", "fields": [ {"name": "title", "selector": "h2", "type": "text"}, {"name": "link", "selector": "a", "type": "attribute", "attribute": "href"}, ], } config = CrawlerRunConfig( cache_mode=CacheMode.BYPASS, css_selector="div.list", # 只在这个容器里干活 extraction_strategy=JsonCssExtractionStrategy(schema), ) result = await crawler.arun(url="https://example.com/list", config=config) data = json.loads(result.extracted_content)

适合列表结构稳定、需要批量入库的页面;换选择器、换 schema,别动流程。

场景 C:LLM 提取不规整页面。页面结构没法用选择器锁死时,用 Pydantic 模型定义你要的字段,让模型按 schema 解析,word_count_threshold=1把内容尽量保留给模型看:

from pydantic import BaseModel, Field from crawl4ai import LLMConfig, LLMExtractionStrategy class ProductFee(BaseModel): name: str = Field(..., description="产品或模型名称") input_fee: str = Field(..., description="输入费用") config = CrawlerRunConfig( cache_mode=CacheMode.BYPASS, word_count_threshold=1, extraction_strategy=LLMExtractionStrategy( llm_config=LLMConfig(provider="openai/gpt-4o", api_token="your-token"), schema=ProductFee.model_json_schema(), instruction="提取文中所有条目及其费用,不要遗漏", ), )

适合定价页、财报这类"人能读懂但 DOM 很乱"的内容,输出同样落在extracted_content

踩坑与避坑指南

现象:启动爬虫后长时间卡住或直接报错,页面一个都加载不了。原因:Playwright 的浏览器内核没装,crawl4ai-setup在部分环境静默失败。 解法:python -m playwright install --with-deps chromium,装完再跑crawl4ai-doctor确认。

现象:raw_markdown里混着导航、页脚、广告,token 烧得心疼。原因:默认只生成 raw 版本,fit_markdown需要显式挂内容过滤器才会产出。 解法:markdown_generator=DefaultMarkdownGenerator(content_filter=PruningContentFilter(threshold=0.4, threshold_type="fixed"))

现象:动态页面抓回来是空壳,只有标题和骨架文本。原因:提取时机早于 JS 异步请求完成,wait_for没设或设小了。 解法:wait_for=5000,或者传一个内容容器的 CSS 选择器,等它出现再提取。

现象:并发量一上来,浏览器内存飙升、页面互相拖慢。原因:并发数超过内存调度器的舒适区,多个页面同时跑重资源请求。 解法:CrawlerRunConfig(semaphore_count=8)压低上限,浏览器侧BrowserConfig(memory_saving_mode=True)降低单页开销。

Crawl4AI 把渲染、清洗、提取压进了同一套异步 API,覆盖"能跑的页面"和"能解析的结构",代价是它的输出质量依赖你给对粒度参数,纯静态小批量场景用它属于杀鸡用牛刀。把第一段代码里的 URL 换成你自己的页面跑一遍,然后按能力二给你的动态页面加一个wait_for——这就是接入生产前的最小闭环。

【免费下载链接】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),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/29 15:24:18

Dify实战:从部署到API发布,搭建简历筛选Agent工作流

8 月 9 日 AI 行业信息量不小&#xff1a;OpenAI 被曝暂停 Astra 项目&#xff0c;Grok Image 2.0 疑似开始灰度推送。对工程师来说&#xff0c;这两条新闻单独看都只是情报&#xff0c;真正能转化为生产力的是工具链本身。这篇文章把新闻快速带过&#xff0c;重点讲一个今天就…

作者头像 李华
网站建设 2026/8/29 15:19:51

电子商务服装产品分类数据集

摘要&#xff1a;电子商务服装产品分类数据集是一个面向服装图像识别、电商商品自动分类与多模态商品理解的大规模视觉数据集&#xff0c;来源于电子商务服装分类基准。数据集概述电子商务服装产品分类数据集是一个面向服装图像识别、电商商品自动分类与多模态商品理解的大规模…

作者头像 李华
网站建设 2026/8/29 15:14:30

Hermes Agent 文献检索与论文写作实战指南

Hermes Agent 文献检索与论文写作实战指南 【免费下载链接】hermes-agent The agent that grows with you 项目地址: https://gitcode.com/GitHub_Trending/he/hermes-agent 每周一早上&#xff0c;你都要翻一遍 arXiv&#xff0c;找出本周和自己研究方向相关的新论文&a…

作者头像 李华
网站建设 2026/8/29 15:14:16

AI编程与工程实践:从AI Agent到团队效能重构的完整指南

最近看到一则消息在技术圈里传得很广&#xff1a;Grindr 的 CEO 公开表示&#xff0c;AI 已经承担了原本 200 名工程师的工作量。对于正在做技术管理、或者正在重新规划职业路线的开发者来说&#xff0c;这个表态确实值得停下来多想几秒。它不是一句简单的“AI 替代人类”的感慨…

作者头像 李华
网站建设 2026/8/29 15:14:12

3D打印积木全攻略:FDM公差控制与参数调优实战指南

Building Blocks — 3D Printing 我最初接触3D printing&#xff0c;就是因为想给孩子做一套市面上买不到的积木。市售拼插积木虽然丰富&#xff0c;但特殊件要么贵得离谱&#xff0c;要么压根不单卖&#xff0c;碰上创意卡壳的时候只能干瞪眼。后来入了FDM打印机&#xff0c;我…

作者头像 李华
网站建设 2026/8/29 15:09:18

PowerToys文本提取器:3步提取屏幕任意文字

PowerToys文本提取器&#xff1a;3步提取屏幕任意文字 【免费下载链接】PowerToys Microsoft PowerToys is a collection of utilities that supercharge productivity and customization on Windows 项目地址: https://gitcode.com/GitHub_Trending/po/PowerToys Power…

作者头像 李华