- 网页爬虫
- 后端
- AI 应用
【免费下载链接】firecrawl
The web data API to search, scrape, and interact at scale. 🔥
本指南基于 FireCrawl 开源仓库中的examples/deepseek-v3-crawler示例,讲解如何用 DeepSeek V3 大语言模型与 FireCrawl Python SDK 构建"目标导向"的网站爬虫:先由 LLM 生成精准的搜索关键词,再通过 Map 接口定位相关页面,最后用 Scrape 接口抓取正文并由模型抽取结构化 JSON。读完本文,你将掌握一个完整的"LLM + Map + Scrape"流水线实现,并理解其底层 SDK 调用机制与可调优的工程细节。
一、示例概览:从"爬全站"到"找答案"
传统的网站爬虫往往"先爬下来再说",浪费大量请求在无关页面上。deepseek-v3-crawler示例改变了这一思路:它把 DeepSeek V3 当作"大脑",把 FireCrawl 的 Map 与 Scrape 当作"手脚",围绕用户给出的**目标(objective)**有方向地抓取信息。
示例文档 README.md 描述的完整流程是:
- 用户输入一个网站 URL 和想要查找的信息目标;
- DeepSeek V3 根据目标生成 1~2 个词的最佳搜索参数;
- 用该参数调用 FireCrawl 的Map功能,找出网站中与目标相关的页面;
- 逐个Scrape最相关的页面,用模型判断目标是否命中;
- 命中后输出结构化 JSON 结果。
这种方式特别适合"从某个站点提取特定信息"的场景,例如从官网提取定价方案、从文档站收集 API 参数、从博客抓取某个主题的文章等。
二、环境准备与前置条件
按照文档要求,运行该示例需要满足:
- Python 3.8+;
- FireCrawl API Key(云服务在
https://api.firecrawl.dev签发); - 一个可访问 DeepSeek V3 推理 API 的密钥。
2.1 关于 LLM 接入方式的说明
README 中描述的是"Hugging Face Inference API",但仓库内实际的脚本实现走的是OpenRouter(base_url="https://openrouter.ai/api/v1"),使用模型标识deepseek/deepseek-chat-v3-0324:free,详见 deepseek-v3-crawler.py。也就是说,当前仓库内以脚本源码为准,README 的 Hugging Face 描述可以视为早期版本或写文档时的规划口径。
因此实际运行时需要的是OpenRouter API Key,脚本会通过环境变量OPENROUTER_API_KEY读取。requirements.txt中的huggingface-hub属于历史依赖,当前脚本并未直接调用它。
2.2 安装步骤
文档给出了三步安装流程,与实际仓库目录对应如下:
第 1 步:克隆仓库并进入示例目录
git clone <repository-url> cd examples/deepseek-v3-crawler第 2 步:安装依赖包
示例的依赖清单在 requirements.txt:
pip install -r requirements.txt依赖内容为:
firecrawl==1.13.5 python-dotenv==1.0.1 huggingface-hub>=0.20.0其中firecrawl==1.13.5是 Python SDK 的固定版本,提供FirecrawlApp客户端;python-dotenv用于从.env文件加载环境变量。
第 3 步:创建.env文件存放密钥
在示例目录(脚本通过load_dotenv()从当前工作目录加载)创建.env:
FIRECRAWL_API_KEY=your_firecrawl_api_key OPENROUTER_API_KEY=your_openrouter_api_key这里与 README 略有出入:README 写的是HUGGINGFACE_API_KEY,而脚本 deepseek-v3-crawler.py 实际读取的是FIRECRAWL_API_KEY与OPENROUTER_API_KEY两个变量,运行时以脚本为准。
三、运行方式与交互流程
在示例目录执行:
python deepseek-v3-crawler.py脚本启动后按顺序:
- 先测试 DeepSeek 模型连通性(发送一条
test消息),失败则直接退出并打印错误详情——这是"快速失败"设计,避免在模型不可用时白白消耗 Map/Scrape 配额; - 提示输入Website(要爬取的网站 URL);
- 提示输入Objective(你想查找的信息目标)。
随后脚本自动进入三阶段流水线,并用 ANSI 彩色输出区分阶段(青色为状态、黄色为进行中、绿色为成功、红色为错误)。
文档给出的示例输入/输出对:
- 输入:网站
https://www.example.com,目标 "Find information about their pricing plans"; - 输出:包含该网站定价信息的结构化 JSON。
四、核心代码逐段解析
脚本体量不大但结构清晰,全部代码在 deepseek-v3-crawler.py。下面按函数拆解。
4.1 初始化:Firecrawl 客户端与 LLM 客户端
app = FirecrawlApp(api_key=firecrawl_api_key) client = OpenAI( base_url="https://openrouter.ai/api/v1", api_key=openrouter_api_key )FirecrawlApp由 Python SDK 导出(见 apps/python-sdk/firecrawl/init.py)。从 SDK 源码看,V1FirecrawlApp的构造函数会优先使用显式传入的api_key,否则读取环境变量FIRECRAWL_API_KEY,并在未提供密钥且指向云服务时抛出ValueError('No API key provided')(见 apps/python-sdk/firecrawl/v1/client.py)。这意味着.env中的FIRECRAWL_API_KEY也可以不显式传入,SDK 会自动读取。
4.2 主流程 main()
主函数 deepseek-v3-crawler.py 的逻辑:
- 用
client.chat.completions.create发送测试请求,若异常则打印红色错误并return; - 交互读取
url与objective; - 调用
find_relevant_page_via_map得到相关页面列表; - 无相关页面则退出;否则调用
find_objective_in_top_pages; - 命中目标则用
json.dumps(result, indent=2)打印结果,未命中则输出提示。
4.3 find_relevant_page_via_map():LLM 生成搜索词 + Map 定位页面
这是整个方案的"智能"所在,代码见 deepseek-v3-crawler.py:
map_prompt = f""" The map function generates a list of URLs from a website and it accepts a search parameter. Based on the objective of: {objective}, come up with a 1-2 word search parameter that will help us find the information we need. Only respond with 1-2 words nothing else. """ response = client.chat.completions.create( model="deepseek/deepseek-chat-v3-0324:free", messages=[{"role": "user", "content": map_prompt}] ) map_search_parameter = response.choices[0].message.content.strip() map_website = app.map_url(url, params={"search": map_search_parameter}) links = map_website.get('urls', []) or map_website.get('links', [])要点:
- 提示词约束输出格式:要求模型"只回答 1~2 个词,不要输出其他内容",这保证了
map_search_parameter可直接作为 Map 的search参数; - Map 的 search 参数语义:在 FireCrawl v1 中,
map_url的search用于对 URL 做关键词过滤(详见下一节 SDK 源码),模型生成的关键词越贴近目标,返回的候选 URL 越相关; - 响应字段兼容处理:脚本同时兼容
urls与links两种响应字段,防止不同版本 API 返回结构差异导致崩溃。
4.4 find_objective_in_top_pages():Scrape + LLM 校验 + JSON 抽取
脚本只取 Map 结果的前 3 个链接逐一尝试,代码见 deepseek-v3-crawler.py:
for link in pages[:3]: scrape_result = app.scrape_url(link, params={'formats': ['markdown']}) check_prompt = f""" Given the following scraped content and objective, determine if the objective is met. If it is, extract the relevant information in a simple JSON format. If the objective is not met, respond with exactly 'Objective not met'. The JSON format should be: {{ "found": true, "data": {{ // extracted information here }} }} Important: Do not wrap the JSON in markdown code blocks. Just return the raw JSON. Objective: {objective} Scraped content: {scrape_result['markdown']} """这段代码有三处值得注意的工程细节:
- 只爬前 3 页:
pages[:3]限制抓取量,控制成本与延迟;Map 已按相关性排序,因此前 3 个通常命中率最高; - 双重校验提示词:system 消息要求模型"始终以合法 JSON 回复、不要用 markdown 代码块包裹",user 消息则要求"未命中时精确返回
Objective not met",形成"命中输出 JSON / 未命中输出标记"的清晰协议; - 防御式 JSON 解析:即便提示词要求不包裹代码块,模型仍可能输出
json ...,因此脚本做了清理——result.split('```')[1]去掉代码块围栏、去掉json前缀再json.loads;解析失败则打印原始响应并继续下一个链接。
解析成功后,校验parsed_result.get('found')是否为真,为真则返回parsed_result.get('data')作为最终抽取结果。
五、底层 SDK 实现:Map 与 Scrape 的调用机制
示例文档没有展开 SDK 内部实现,但结合仓库源码可以更深入地理解这两个调用点。示例锁定的firecrawl==1.13.5对应仓库中 Python SDK 的 v1 实现 apps/python-sdk/firecrawl/v1/client.py。
5.1 map_url:网站页面发现与 search 过滤
map_url的实现位于 apps/python-sdk/firecrawl/v1/client.py,其签名支持一批可选参数:
| 参数 | SDK 中对应请求字段 | 作用 |
|---|---|---|
search | search | 过滤 URL 的关键词模式,正是示例中由 LLM 生成的参数 |
ignore_sitemap | ignoreSitemap | 跳过sitemap.xml处理 |
include_subdomains | includeSubdomains | 是否包含子域名链接 |
sitemap_only | sitemapOnly | 仅使用 sitemap 作为来源 |
limit | limit | 返回的最大 URL 数量 |
timeout | timeout | 请求超时(毫秒),默认 30000 |
use_index | useIndex | 是否使用索引 |
location | location | 地域配置 |
SDK 内部会把这些参数组装进V1MapParams,然后以POST {api_url}/v1/map提交,携带Authorization: Bearer {api_key},并自动附加origin: python-sdk@{version}标识。返回 200 且success为真时,得到包含links列表的V1MapResponse。
这也解释了示例脚本为什么用app.map_url(url, params={"search": map_search_parameter}):params字典会原样透传给请求,search让站点地图发现聚焦在目标主题上。
5.2 scrape_url:抓取正文并返回 markdown
scrape_url的实现位于 apps/python-sdk/firecrawl/v1/client.py。示例使用params={'formats': ['markdown']}要求返回 Markdown 格式正文,这是后续喂给 LLM 的关键输入。
SDK 支持多种formats值,除markdown外还包括html、rawHtml、content、links、screenshot、screenshot@fullPage、extract、json、changeTracking。formats之外,scrape_url还支持headers、include_tags、exclude_tags、only_main_content、wait_for、timeout(毫秒,默认 30000)、mobile、proxy(basic/stealth/enhanced/auto)、parse_pdf、actions、change_tracking_options、zero_data_retention等参数。
请求同样发往POST {api_url}/v1/scrape,返回的V1ScrapeResponse中携带请求的格式内容与页面元数据;示例通过scrape_result['markdown']取出正文。
5.3 关于 FirecrawlApp 与统一客户端
仓库当前 Python SDK 已演进为"统一客户端"模式:Firecrawl类(见 apps/python-sdk/firecrawl/client.py)默认暴露 v2 API(scrape、map、crawl、search、extract等),同时通过.v1子对象保留 v1 方法(scrape_url、map_url)供渐进迁移。示例使用的FirecrawlApp是 v1 时代的类名,firecrawl==1.13.5固定版本保证了示例的可复现性;升级 SDK 版本时需要注意方法名与参数风格的差异(v2 中对应为app.map(url, params=...)、app.scrape(url, params=...))。
六、输出格式与 JSON 抽取约定
成功时脚本打印如下结构的 JSON(indent=2美化):
{ "found": true, "data": { "plan_name": "Pro", "price": "$49/month", "features": ["..."] } }注意:最外层found是模型与脚本之间的协议字段,并不会出现在最终输出中——脚本只打印parsed_result.get('data')。这个约定的意义在于:
- 模型只需遵循固定的
{"found": bool, "data": {...}}结构; - 脚本据此判断"这一页是否命中",未命中就继续爬下一页;
data字段的内容完全由模型按目标自由组织,因此该方案无需预定义 JSON Schema,属于"prompt 驱动的自由抽取",与 SDK 中需要 schema 的extract接口(在 apps/python-sdk/firecrawl/v1/client.py,且当前已标记为 maintenance 模式)形成对比。
七、参数调优与扩展建议
README 的 Notes 部分提醒:可以按需调整脚本中的temperature或max_new_tokens。结合源码,给出更具体的调优方向:
- 模型参数:
client.chat.completions.create调用目前未显式传temperature,DeepSeek 默认值即可满足大多数场景;若发现 Map 关键词生成不够精准,可适当降低temperature(如 0.2~0.5)让关键词更稳定;若目标需要长篇幅抽取,可调高max_tokens。 - 候选页数量:
pages[:3]可按配额与命中率权衡调整。配额充足时可增加候选数;追求速度与低成本时保持 3 个以内。 - scrape 参数:
formats可加入links便于模型结合页面链接推理;对 JS 渲染站点可设置wait_for或actions等待动态内容加载。 - 错误处理:脚本对"模型不可用"做了前置探测,但 Map 返回空链接、JSON 解析失败时也会优雅降级为提示后退出,适合作为模板扩展到批量场景(例如改为从文件读取多个 URL 与目标)。
八、总结:一条可复用的"LLM 定向爬取"流水线
deepseek-v3-crawler示例演示了一种高度可复用的模式:用 LLM 的语义理解能力替代人工配置爬取规则。核心链路可以概括为:
Objective ──LLM──> search 关键词 ──map_url──> 候选 URL 列表 候选 URL 前 N 个 ──scrape_url(markdown)──> 页面正文 正文 + Objective ──LLM──> {"found": true, "data": {...}} 或 "Objective not met"阅读本文后,你可以直接运行 deepseek-v3-crawler.py 体验完整流程,也可以把find_relevant_page_via_map与find_objective_in_top_pages两个函数拆出来,嵌入到自己的数据采集、竞品分析或文档整理任务中。仓库中同目录的 README.md 与 requirements.txt 是快速复现的直接依据,SDK 的 v1/client.py 则是理解每个参数底层行为的最佳参考。
- 网页爬虫
- 后端
- AI 应用
【免费下载链接】firecrawl
The web data API to search, scrape, and interact at scale. 🔥
相关推荐
用 PocketFlow 打造 LLM 驱动的网站爬虫与分析流水线:pocketflow-tool-crawler 实战指南
用 PocketFlow 打造 LLM 驱动的网站爬虫与分析流水线:pocketflow tool crawler 实战指南 本文是一份基于 PocketFlo
人工智能大模型AI Agent工作流自动化RAGAutoGPT 平台 Firecrawl Crawl 块详解:以 Firecrawl 驱动整站爬取与内容提取
AutoGPT 平台 Firecrawl Crawl 块详解:以 Firecrawl 驱动整站爬取与内容提取 导读 Firecrawl Crawl 是 Auto
人工智能AI Agent自主智能体Agent 工作流工作流自动化后端前端如何快速上手MiMo-V2.6-Pro-RL:从下载到首次响应的5步教程,零门槛入门全模态Agent大模型
如何快速上手MiMo V2.6 Pro RL:从下载到首次响应的5步教程,零门槛入门全模态Agent大模型 MiMo V2.6 Pro RL 是小米 MiMo
人工智能大模型基础模型多模态强化学习
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考