拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

DeepSeek V3 Web Crawler 实战指南:LLM 驱动的目标化网站爬取方案(FireCrawl 开源仓库示例)

DeepSeek V3 Web Crawler 实战指南:LLM 驱动的目标化网站爬取方案(FireCrawl 开源仓库示例)
  • 网页爬虫
  • 后端
  • AI 应用

【免费下载链接】firecrawl

The web data API to search, scrape, and interact at scale. 🔥

项目地址:https://gitcode.com/GitHub_Trending/fi/firecrawl
点击查看免费下载

本指南基于 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 描述的完整流程是:

  1. 用户输入一个网站 URL 和想要查找的信息目标;
  2. DeepSeek V3 根据目标生成 1~2 个词的最佳搜索参数;
  3. 用该参数调用 FireCrawl 的Map功能,找出网站中与目标相关的页面;
  4. 逐个Scrape最相关的页面,用模型判断目标是否命中;
  5. 命中后输出结构化 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

脚本启动后按顺序:

  1. 先测试 DeepSeek 模型连通性(发送一条test消息),失败则直接退出并打印错误详情——这是"快速失败"设计,避免在模型不可用时白白消耗 Map/Scrape 配额;
  2. 提示输入Website(要爬取的网站 URL);
  3. 提示输入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 的逻辑:

  1. 用client.chat.completions.create发送测试请求,若异常则打印红色错误并return;
  2. 交互读取url与objective;
  3. 调用find_relevant_page_via_map得到相关页面列表;
  4. 无相关页面则退出;否则调用find_objective_in_top_pages;
  5. 命中目标则用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']} """

这段代码有三处值得注意的工程细节:

  1. 只爬前 3 页:pages[:3]限制抓取量,控制成本与延迟;Map 已按相关性排序,因此前 3 个通常命中率最高;
  2. 双重校验提示词:system 消息要求模型"始终以合法 JSON 回复、不要用 markdown 代码块包裹",user 消息则要求"未命中时精确返回Objective not met",形成"命中输出 JSON / 未命中输出标记"的清晰协议;
  3. 防御式 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 中对应请求字段作用
searchsearch过滤 URL 的关键词模式,正是示例中由 LLM 生成的参数
ignore_sitemapignoreSitemap跳过sitemap.xml处理
include_subdomainsincludeSubdomains是否包含子域名链接
sitemap_onlysitemapOnly仅使用 sitemap 作为来源
limitlimit返回的最大 URL 数量
timeouttimeout请求超时(毫秒),默认 30000
use_indexuseIndex是否使用索引
locationlocation地域配置

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。结合源码,给出更具体的调优方向:

  1. 模型参数:client.chat.completions.create调用目前未显式传temperature,DeepSeek 默认值即可满足大多数场景;若发现 Map 关键词生成不够精准,可适当降低temperature(如 0.2~0.5)让关键词更稳定;若目标需要长篇幅抽取,可调高max_tokens。
  2. 候选页数量:pages[:3]可按配额与命中率权衡调整。配额充足时可增加候选数;追求速度与低成本时保持 3 个以内。
  3. scrape 参数:formats可加入links便于模型结合页面链接推理;对 JS 渲染站点可设置wait_for或actions等待动态内容加载。
  4. 错误处理:脚本对"模型不可用"做了前置探测,但 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. 🔥

项目地址:https://gitcode.com/GitHub_Trending/fi/firecrawl
点击查看免费下载

相关推荐

上一篇:打破英语输入瓶颈:Qwerty Learner如何让你的键盘记忆与单词学习同步提升
下一篇:43秒解锁星露谷物语资源:StardewXnbHack让MOD制作变得如此简单

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

返回列表