Firecrawl深度调研报告:功能、实现原理、架构与自研落地建议

Firecrawl 深度调研报告:功能、实现原理、架构与自研落地建议

调研时间:2026-08-12

数据来源:GitHub 官方仓库(firecrawl/firecrawl,main 分支实时抓取)、官方文档 docs.firecrawl.dev、源码关键文件

调研方式:GitHub API + raw 直链源码分析(未 clone,仓库 174MB)


1. 项目概述

维度 数据
项目名 Firecrawl 🔥
定位 The context API to search, scrape, and interact with the web at scale(网页上下文 API:搜索、抓取、交互)
GitHub Stars 165,863(截至 2026-08-12)
Forks 9,321
主语言 TypeScript
许可证 AGPL-3.0(SDK 为 MIT)
创建时间 2024-04-15
最近提交 2026-08-11(活跃度极高,几乎每日提交)
仓库大小 174 MB(monorepo)
商业模式 开源核心 + 云 SaaS(firecrawl.dev),云版有额外功能

一句话定位 :把"网页抓取"从工程问题变成"一次 API 调用"。用户不需要关心代理轮换、JS 渲染、反爬绕过、Markdown 清洗------Firecrawl 声称覆盖 96% 的网页 ,P95 延迟 3.4 秒(百万级页面实测)。

发展脉络(从代码仓库可清晰看出):

  • v0/v1:纯 Scrape → Crawl → Extract 三件套(提取网页为 Markdown)
  • v2(2025 下半年):升级为 Search + Scrape + Interact + Agent 四大核心 + Batch/Crawl/Map,引入自研 Fire-engine 浏览器渲染引擎
  • 2026:加入 Spark 模型(自研 LLM)、Research(学术搜索)、Ask(文档问答)、Browser API(持久浏览器会话)、Deep Research 等企业能力

2. 功能全景清单

2.1 四大核心端点(v2)

端点 功能 关键参数/能力
/v2/scrape 单 URL 抓取,转 Markdown/HTML/截图/JSON formats: markdown/html/screenshot/json/rawHtmlactions(点击/滚动/输入/等待/按键);waitFor(等待选择器/网络空闲);mobile(移动端模拟);geolocation(地理位置);skipTlsVerificationproxy: basic/stealth
/v2/search 搜索引擎结果 + 自动抓取全文 底层接 SearXNG 等元搜索;返回 url/title/markdown;支持 locationcountrylimitlangscrapeOptions
/v2/interact 在已抓取页面上用 自然语言提示词 交互 POST /v2/scrape/{scrapeId}/interact,prompt 如 "Search for mechanical keyboard" → 返回 output + liveViewUrl(实时视频画面);底层是自研浏览器 Agent(lib/scrape-interact/browser-agent.ts
/v2/agent 自主数据收集:描述需求,AI 自动搜索/导航/抓取 prompt(无 URL 也可);可选 schema(结构化输出,pydantic/zod);可选 urls(聚焦指定页面);model: spark-1-mini(默认,便宜 60%)/ spark-1-pro。是 /extract 的进化版,不需要预先知道 URL

2.2 批量与站点级端点

端点 功能 说明
/v2/crawl 全站爬取(异步任务) limitmaxDepthincludePaths/excludePaths(正则)、ignoreSitemapallowSubdomains;返回 jobId,GET /v2/crawl/{id} 轮询;WebSocket 实时进度;可 cancel
/v2/map 站点 URL 发现 优先读 sitemap.xml,再回退爬取页面提取链接;search 参数按相关性排序(map-cosine.ts 余弦相似度);limitignoreSitemap
/v2/batch/scrape 一次抓取上千 URL 异步任务,formats 统一或按 URL 指定;webhook 通知
/v2/parse 文档解析(无浏览器 直接从 HTTP 拉取 PDF/DOCX/XLSX/PPTX/RTF/ODT 等,用 Go 库解析为 Markdown;parseApi.ts
/v2/browser 持久浏览器会话管理 create/execute/delete/list;session 内保持登录态、cookies;可执行 JS、截图、导航(scrape-browser.ts

2.3 监控与研究类端点(企业级)

端点 功能 说明
Monitor/v2/monitor 网页变化监控 create/update/run/delete;按 schedule 抓取对比,变化时发通知;分 Page(页面)/ Website(全站)/ Web-scale(全网)三档
Research/v2/research 学术论文搜索/获取 research-paperresearch-search-papersresearch-related-papers;学术类垂直搜索
/v2/ask 文档问答 对抓取内容做 RAG 问答(features/ask
Change Tracking 页面 diff transformers/diff.ts,两个时间点的 Markdown diff

2.4 支撑性能力

能力 说明
Actions 抓取前执行浏览器动作序列:clickscrolltypewaitpressscreenshotgetCookiesexecuteJavascriptfile(下载)、pdf
LLM 结构化提取 /v2/scrapejson format + schema;或 extract 端点:从 URL 列表/搜索词中提取结构化数据(lib/extract/
Screenshot 视口截图 + 全页截图(screenshot@fullScreen
PDF 引擎 专门处理 PDF:提取文本、OCR(engines/pdf/)、页面级 Markdown
文档转换 DOCX/XLSX/PPTX/RTF/ODT → Markdown/HTML(engines/document/
PII 脱敏 transformers/redactPII.ts,从抓取结果中删除姓名/邮箱/电话等
Branding 品牌元素检测:logo、品牌色、声明式 logo 校验(lib/branding/
锁定模式 Lockdown 只允许从白名单域名抓取(企业安全)
Keyless 免密 无需 API key 的免费额度(按 IP 限流,lib/keyless.ts
威胁防护 Google Web Risk 域名风险检查 + PII 过滤(lib/threat-protection/
Zero Data Retention (ZDR) 完成后立即清除中间数据(合规)
Webhooks 异步任务完成通知;支持自托管 webhook

2.5 集成生态

  • 8 种官方 SDK :Python(firecrawl-py)、Node.js、Go、Java、Rust、Ruby、.NET、PHP、Elixir
  • MCP Serverfirecrawl-mcp,一行配置接入任意 MCP 客户端
  • CLI + Agent Skillsfirecrawl CLI、firecrawl-skills(Claude Code/Codex/OpenCode 等直接可用)
  • Workflowsfirecrawl-workflows(可复用的抓取工作流)
  • Agent Onboarding:AI Agent 可通过 SKILL.md 引导用户注册拿 key
  • 平台集成:Zapier、n8n、Lovable、LangChain、CrewAI、Dify、Flowise 等 17+ 集成

2.6 开放与云版差异

开源版(自托管)包含核心 Scrape/Crawl/Map/Batch/Search/Extract;云版额外提供:Fire-engine 高级反爬、Agent/Interact/Ask、Research、监控、品牌等企业功能。README 明确说明开源核心为 AGPL-3.0。


3. 核心实现原理

3.1 抓取引擎瀑布流(Scrape 的核心机制)⭐

源码:apps/api/src/scraper/scrapeURL/engines/index.ts

设计思想 :不依赖单一抓取方式,而是维护一个多引擎按质量排序的候选列表,用"瀑布流"(waterfall)并发调度,先到先得,失败自动降级到下一个引擎。

引擎清单与质量分
引擎 quality 适用场景
exchange 2000 交换站/缓存交换(最新引入)
index 1000 索引缓存命中(services/index.ts,Redis/Postgres 缓存,总是最先尝试
fire-engine;chrome-cdp 50 自研全功能浏览器引擎(JS 渲染、actions、截图)
fire-engine(retry);chrome-cdp 45 同上,带重试
playwright 20 轻量 Playwright 引擎
fire-engine;tlsclient 10 TLS 指纹 HTTP 客户端(轻量反检测)
fetch 5 纯 HTTP GET 兜底(undici)
pdf / document -20 专用解析器(非 HTML 内容,负分 = 仅特殊场景使用)
调度算法
复制代码
1. 根据请求格式生成 Feature Flags(actions/screenshot/pdf/mobile/waitFor/...)
2. 计算每个引擎的 supportScore = Σ(支持的 flag × flag 权重)
3. 筛选 supportScore >= totalPriority/2 的引擎;若存在 quality>0 引擎则剔除 quality<0 的
4. 按 supportScore↓ → quality↓ 排序
5. 主循环:
   a. 取出下一个引擎并发启动 scrape
   b. Promise.race([所有活跃引擎, 瀑布流超时器, 整体超时器])
   c. 某引擎成功(内容非空 + 状态码 2xx/304 + 无页面错误)→ 返回
   d. 失败 → 移除该引擎,继续
   e. 瀑布流超时(引擎太慢)→ 启动下一个引擎(多引擎并行竞争)
6. 全部失败 → NoEnginesLeftError
质量评估三要素
typescript 复制代码
const isLongEnough = markdown.trim().length > 0;      // 内容非空
const isGoodStatusCode = 200-299 || 304;              // 状态码正常
const hasNoPageError = engineResult.error === undefined; // 无页面错误

关键细节 :401/403/429 + proxy="auto" → 自动添加 stealthProxy flag 重试(反爬自动升级)。AbortManager 管理三级超时(Scrape 整体 / 引擎 / URL)。

这正是多引擎抓取架构的经典设计,本次调研从源码实时确认。

3.2 HTML → Markdown 转换(Go 微服务)

源码:apps/api/sharedLibs/go-html-to-md/html-to-markdown.go + lib/html-to-markdown-client.ts

为什么用 Go :源码注释明确说明------"避免阻塞 Node.js 事件循环"。HTML→Markdown 是 CPU 密集转换,用 Go 编译为 C 共享库(-buildmode=c-shared)通过 N-API 调用,或独立 HTTP 微服务。

go 复制代码
converter := md.NewConverter("", true, nil)
converter.Use(plugin.GitHubFlavored())   // GFM:表格、任务列表、删除线
converter.Use(plugin.RobustCodeBlock())  // 代码块保护
markdown, err := converter.ConvertString(html)

基于 github.com/firecrawl/html-to-markdown(Go 版 turndown 风格转换器)。

3.3 Transformers 管线(文档后处理链)

源码:apps/api/src/scraper/scrapeURL/transformers/index.ts

抓到的原始内容不是直接返回,而是经过一条有序的 transformer 管线

复制代码
engine 原始结果
  → rawHtml          (原始 HTML)
  → html             (htmlTransform:移除 script/style/nav/footer 等噪声元素)
  → markdown         (Go 服务转换,按需)
  → metadata         (title/description/og 标签/sourceURL)
  → links            (extractLinks:解析 <a href>)
  → images           (extractImages:提取图片 URL)
  → 各 format 分支:
      ├─ json  → deterministicJson(CSS/XPath schema 提取)或 LLM extract
      ├─ summary → LLM 摘要
      ├─ query → LLM 问答
      ├─ agent → Agent 交互
      ├─ attributes → 属性提取
      ├─ product/menu → 电商/菜单专用 schema
      ├─ audio/video → 音视频信息提取
      ├─ redactPII → 脱敏
      ├─ diff → 变化追踪
      └─ sendToSearchIndex → 索引

设计要点 :每个 transformer 依赖前序输出(requireRawHtml() / 检查 document.html === undefined 报错),形成严格的 DAG,保证顺序正确性。

3.4 LLM 结构化提取(Extract/Agent 核心)

源码:apps/api/src/scraper/scrapeURL/transformers/llmExtract.tslib/extract/(含 fire-0 新一代)

流程

复制代码
抓取 URLs → 合并 Markdown → trimToTokenLimit() 截断
→ 选择模型 → generateObject({ schema, prompt, system })(Vercel AI SDK)
→ 校验/修正 → 计费 → 返回 { data, sources, llmUsage }

模型选择(智能)

typescript 复制代码
selectModelForSchema(schema):
  无 schema → gpt-4o-mini
  含 $ref/$defs/definitions(递归 schema)→ gpt-4.1(更强)
  简单 schema → gpt-4o-mini(省钱)

Schema 规范化 normalizeSchema()

  • type: object → 全部字段 required、additionalProperties: false
  • 递归处理 $defs / anyOf / oneOf / allOf

Token 截断(防事件循环阻塞 + 精确控制):

复制代码
1. maxTokens × 5 chars 字符级预截断(快速,防阻塞)
2. tiktoken encoding_for_model() 精确计数
3. tokens.slice(0, maxTokens) → decode 回文本
4. 兜底:charsPerToken=2.8 估算

失败重试 :配额超限/速率限制 → 自动降级到 retryModel(gpt-4.1-mini)。LLM 拒绝提取(版权/内容政策)→ 抛 LLMRefusalError

Agent(fire-0 新一代提取)lib/extract/fire-0/ 使用独立完成管线 completions/,支持自研 Spark 模型(spark-1-mini / spark-1-pro),有 reranker(重排序)和 URL 处理器。

3.5 Fire-engine:自研浏览器渲染引擎(云版核心壁垒)

源码:apps/api/src/scraper/scrapeURL/engines/fire-engine/

Fire-engine 是 Firecrawl 自研的托管浏览器集群(不在开源仓库内,通过 HTTP API 调用):

引擎类型 用途
chrome-cdp 完整 Chrome DevTools Protocol 浏览器:执行 actions、截图、移动模拟、地理定位、持久存储
tlsclient 轻量 TLS 指纹 HTTP 客户端:无头请求 + 反检测(模仿真实浏览器 TLS 指纹)

请求字段scrape.tsFireEngineScrapeRequestChromeCDP):engineactions[]blockMediamobilegeolocationtimeoutmaxAgezeroDataRetentionpersistentStorage.uniqueId(会话保持)。

响应content(HTML)、pageStatusCodescreenshots[]actionResults[](每个 action 的截图/抓取结果)、file(下载文件)、docUrl(GCS 暂存)、youtubeTranscriptContent(YouTube 字幕)。

反爬自动升级 :fire-engine 失败且返回 retryWithStealth: true → API 层自动改用 stealth 代理重试。

3.6 Engpicker:AI 驱动的引擎选择器(2026 新架构)

源码:apps/api/src/lib/engpicker.ts + Rust native(@mendable/firecrawl-rs

问题 :不同网站对抓取方式的偏好不同(有的静态、有的 JS、有的强反爬)。Engpicker 为每个域名学习最优引擎

复制代码
1. 对未知域名:尝试各引擎抓取(basic/stealth 代理)
2. 用 GPT-4o-mini 评估抓取质量("这个 markdown 是否成功抓取了内容")
3. 计算 verdict(Rust 侧 computeEngpickerVerdict)
4. 按 domain_level(域名层级)缓存结论到 PostgreSQL(engpicker_jobs 表)
5. 后续同域名请求直接命中推荐引擎

这解释了 Firecrawl "越用越准" 的特性------按域名积累抓取经验

3.7 Index 索引缓存(为什么"快")

源码:apps/api/src/services/index.tsservices/indexing/

index 引擎 quality=1000 总被最先尝试。它维护了一个网页内容索引缓存(Redis/PostgreSQL 双后端):

  • 同一 URL 再次请求 → 直接命中缓存(maxAge 控制新鲜度)
  • 支持 useIndex / useSearchIndex 两级
  • 索引 worker(index-worker.ts)后台持续构建
  • Engpicker 与 index 配合:缓存不命中才走引擎瀑布流

3.8 Crawl 编排(多页爬取)

源码:apps/api/src/scraper/crawler/lib/crawl-redis.tsservices/queue-*

状态存储(Redis)

用途
crawl:{id} 任务元数据 JSON
crawl:{id}:url:{hash} URL 去重锁(NX,24h TTL)
crawl:{id}:jobs 已入队集合
crawl:{id}:jobs_done 已完成集合
crawl:{id}:robots_blocked 被 robots.txt 阻止的 URL

工作器循环

复制代码
processJobInternal(job):
  1. scrapeURL() → Document
  2. extractLinksFromHTML(html) → <a href> 列表
  3. filterLinks(links, maxDepth) → 12 种过滤链:
     URL 解析 → 非 web 协议 → #锚点 → 深度检查 → excludes 正则
     → includes 正则 → 外部域名 → 子域名 → 反向爬取检查
     → 社交媒体 → 文件类型 → robots.txt
  4. checkUrlsAgainstThreatPolicy() → 威胁过滤
  5. 对每个通过链接: lockURL()(去重)→ 入队
  6. 计费 + 日志 + Webhook

队列双后端(NuQ) :默认 PostgreSQL(apps/nuq-postgres,带 pg_cron),可选 FoundationDBNUQ_BACKEND=fdb,实验性,更适合超大规模)。RabbitMQ 做任务分发。

3.9 搜索实现

源码:apps/api/src/search/lib/search-query-builder.ts

  • 自托管用 SearXNG(开源元搜索)聚合多个引擎
  • 云版接自研/商业搜索索引(search-index-client.ts
  • 结果自动送 scrape 管线抓全文 → 返回 markdown
  • search-query-builder.ts 负责把查询改写适配不同后端

3.10 安全与合规

  • Threat Protection :Google Web Risk(域名风险查杀)+ 域名黑名单 + PII 检测(lib/threat-protection/
  • ZDR :完成后立即删除中间数据(zdr-helpers.ts
  • robots.txt :默认遵守(lib/robots-txt.tsshouldCheckRobots.ts 按策略跳过)
  • Keyless 限流 :按 IP 每日配额(lib/keyless.ts),Spur Context API 检测代理/VPN 滥用
  • IP/Key 白名单 :企业可用(lib/ip-restriction.tskey-restriction.ts

4. 系统架构

4.1 逻辑分层

复制代码
┌────────────────────────────────────────────────────────────┐
│                    客户端层 (SDK/CLI/MCP/Skills)             │
│  Python · Node · Go · Java · Rust · Ruby · .NET · PHP      │
└──────────────────────────┬─────────────────────────────────┘
                           │ HTTPS
┌──────────────────────────▼─────────────────────────────────┐
│                    API 层 (Express + TypeScript)            │
│  routes → controllers/v1, v2 → 校验 (zod) → 计费 → 调度      │
└──────────────────────────┬─────────────────────────────────┘
                           │
┌──────────────────────────▼─────────────────────────────────┐
│                核心抓取层 (scraper/scrapeURL)               │
│  ┌──────────────────────────────────────────────────────┐  │
│  │           引擎瀑布流 (Engines Waterfall)             │  │
│  │  exchange(2000) → index(1000) → fire-engine(50)     │  │
│  │  → fire-engine-retry(45) → playwright(20)           │  │
│  │  → tlsclient(10) → fetch(5) → pdf/doc(-20)          │  │
│  └──────────────────────────────────────────────────────┘  │
│              ↓                                             │
│  Transformers 管线: rawHtml→html→markdown→metadata→links   │
│  →images→LLM extract/summary/query/agent/redactPII/diff    │
└──────────────────────────┬─────────────────────────────────┘
                           │
┌──────────────────────────▼─────────────────────────────────┐
│              执行引擎集群 (独立服务/容器)                    │
│  Fire-engine (chrome-cdp / tlsclient)                      │
│  Playwright 微服务 (playwright-service-ts)                 │
│  Go HTML→Markdown 服务                                     │
│  PDF 解析 (fire-pdf/runpod) + 文档解析 (Go)                 │
└──────────────────────────┬─────────────────────────────────┘
                           │
┌──────────────────────────▼─────────────────────────────────┐
│              基础设施层                                     │
│  Redis (缓存/去重/限流) · PostgreSQL (NuQ队列/Engpicker)    │
│  RabbitMQ (任务分发) · FoundationDB (可选队列后端)          │
│  ClickHouse (并发日志) · GCS (中间结果暂存)                 │
└────────────────────────────────────────────────────────────┘

4.2 monorepo 结构(apps/)

复制代码
apps/
├── api/                  # 主 API 服务(Express + TS,核心抓取逻辑)
│   └── src/
│       ├── controllers/  # v0/v1/v2 路由控制器
│       ├── scraper/
│       │   ├── scrapeURL/    # ⭐ 核心:引擎瀑布流 + transformers
│       │   │   ├── engines/  #   exchange/index/fire-engine/playwright/fetch/pdf/document/wikipedia/x-twitter
│       │   │   ├── transformers/  # llmExtract/agent/deterministicJson/product/menu/audio/video/diff/redactPII
│       │   │   ├── postprocessors/  # youtube 等
│       │   │   └── lib/      #   abortManager/extractLinks/extractMetadata/smartScrape
│       │   ├── crawler/     # sitemap 爬取
│       │   └── WebScraper/  # 旧版抓取器 + sitemap
│       ├── lib/          # engpicker/extract/deep-research/html-to-markdown/robots-txt/threat-protection/keyless/...
│       ├── services/     # index 缓存/queue 队列/webhook/billing/rate-limiter/redis
│       ├── search/       # SearXNG 搜索集成
│       ├── db/           # Drizzle ORM schema
│       ├── native/       # Rust 原生模块 (crawler/document/engpicker)
│       └── sharedLibs/   # Go 共享库 (go-html-to-md)
├── playwright-service-ts/ # Playwright 浏览器微服务
├── go-html-to-md-service/ # Go HTML→Markdown 微服务
├── nuq-postgres/          # NuQ 队列 PostgreSQL 镜像(pg_cron)
├── redis/                 # Redis 配置
├── ui/                    # 管理界面 (ingestion-ui, React)
├── test-site/             # 测试站点
├── test-suite/            # 评测套件 (含 load-test)
└── *-sdk/                 # 8 种语言 SDK

4.3 关键设计模式

  1. Scrape 为一切的核心 :Crawl 每页 = scrapeURL();Extract/Agent = 多次 scrape + LLM。scrapeURL() 是所有功能的公共地基。
  2. 质量分驱动的引擎竞争:不 try/catch 串行,而是并发竞争 + 瀑布流超时,兼顾速度与成功率。
  3. Go/Rust 混合加速:HTML→Markdown 用 Go(c-shared),引擎选择计算用 Rust(WASM/native),避免阻塞 Node 事件循环。
  4. 索引缓存 + Engpicker 学习:同一域名第二次抓取即可命中经验缓存,这是与普通爬虫的本质差异。
  5. ZDR 设计:大文件(截图/PDF)存 GCS 临时桶,完成后清理,合规友好。

5. 部署架构

5.1 Docker Compose(官方自托管)

服务清单(docker-compose.yaml):

服务 镜像/构建 资源限制 用途
api 构建 apps/api 或 ghcr.io/firecrawl/firecrawl 4 CPU / 8G 主 API + 全部 worker(harness 启动)
playwright-service 构建 apps/playwright-service-ts 2 CPU / 4G Playwright 浏览器微服务(MAX_CONCURRENT_PAGES
redis redis:alpine --- 缓存/去重/限流
rabbitmq rabbitmq:3-management --- 任务队列分发
nuq-postgres 构建 apps/nuq-postgres --- NuQ 队列后端(pg_cron 调度)
foundationdb foundationdb/foundationdb:7.3.63 --- 可选队列后端(NUQ_BACKEND=fdb

关键环境变量:

  • NUM_WORKERS_PER_QUEUE=8CRAWL_CONCURRENT_REQUESTS=10MAX_CONCURRENT_JOBS=5BROWSER_POOL_SIZE=5
  • OPENAI_API_KEY / OLLAMA_BASE_URL(LLM 提取需要,可换 OpenAI 兼容端点)
  • SEARXNG_ENDPOINT(搜索功能)
  • PROXY_SERVER/PROXY_USERNAME/PROXY_PASSWORD(代理池)
  • NUQ_BACKEND=fdb 切换 FoundationDB

自托管注意(SELF_HOST.md 明确警告):

  • 默认 API 无认证USE_DB_AUTHENTICATION=false),离开可信网络必须先加认证 + TLS
  • Compose 无持久卷 → 数据不保证存活,生产需自配备份
  • 自托管不含 Fire-engine(云版专属)→ 反爬能力弱于云版

5.2 Kubernetes

  • examples/kubernetes/cluster-install/:api / worker / playwright-service / redis / nuq-postgres 的 YAML
  • examples/kubernetes/firecrawl-helm/:完整 Helm chart(values.yaml + overlays dev/prod),含 RabbitMQ、cclog-worker、extract-worker、nuq-prefetch-worker 等

5.3 可观测性

  • ClickHouse 并发日志(clickhouse/concurrency_logs.sql
  • Sentry、OpenTelemetry(lib/otel-tracer.ts)、Prometheus metrics(admin/metrics)
  • 日志分级:winston + LOGGING_LEVEL

6. 技术栈明细

技术
语言 TypeScript(主)、Go(HTML→MD)、Rust(native 计算)
Web 框架 Express 5(v2 测试 express5.test.ts
校验 Zod(全部请求/响应 schema 校验)
ORM Drizzle(PostgreSQL)
AI SDK Vercel AI SDK(generateObject/generateText)+ tiktoken
LLM OpenAI GPT 系列 + 自研 Spark 模型(云)+ 可接 Ollama/兼容端点
队列 NuQ(PostgreSQL 默认 / FoundationDB 可选)+ RabbitMQ + Bull
缓存/状态 Redis(去重锁/限流/会话)
浏览器 自研 Fire-engine + Playwright 微服务
反爬 TLS 指纹客户端 + stealth 代理 + 代理轮换
存储 PostgreSQL、Redis、GCS(临时文件)、ClickHouse(日志)
部署 Docker Compose、K8s + Helm、GitHub Actions CI/CD

7. 自研落地建议(重点)

若要在自研项目中实现类似 Firecrawl 的能力,基于本次调研的源码级理解,可参考以下分层建议。

7.1 先想清楚:你要做哪个"级别"的 Firecrawl?

级别 对应能力 工作量 推荐
L1 单页抓取 API scrape → markdown/html/json 1-2 周 ⭐ 先做这个
L2 多引擎 + 瀑布流 静态/JS/反爬自动降级 +1-2 周 ⭐ 核心差异点
L3 全站爬取 crawl + map + 去重 + 队列 +1-2 周 视需求
L4 LLM 提取 extract/agent(schema 结构化) +1-2 周 结合免费模型
L5 企业能力 监控/搜索/浏览器会话/反爬集群 数月 商业化再说

7.2 L1:单页抓取 API(地基)

必须复刻的架构模式:Scrape → Transformers 管线分层。

复制代码
输入: URL + formats + options
  ↓
1. 抓取层(先简单:HTTP 客户端 + 可选 Playwright)
  ↓
2. Transformers 管线(严格顺序):
   rawHtml → html(去噪)→ markdown → metadata → links → images
   ↓
3. 按 formats 输出: markdown / html / json / screenshot

关键实现要点

  • HTML→Markdown 别用 Python 现成库硬扛 。可参考 Firecrawl 用独立进程/服务做转换(Python 可考虑 markdownify + 自定义 boilerplate 过滤,或用已有的 Crawl4AI 输出)。⚠️ 如果追求高质量,Firecrawl 用的 Go 库 firecrawl/html-to-markdown 是开源可复用的。
  • 去噪是关键质量分水岭 :移除 script/style/nav/footer/广告,保留正文结构。Firecrawl 的 removeUnwantedElements.ts + Go 转换器是核心。可借鉴 Crawl4AI 的 PruningContentFilter。
  • 超时管理:三明治超时(整体 / 引擎 / 单 URL),防止慢页面卡死整个服务。
  • 字符集处理 :Firecrawl 的 fetch 引擎先读 header charset → 再读 meta charset → UTF-8 兜底(decodeHtmlBuffer),这是中文本地化最容易踩的坑。

7.3 L2:多引擎瀑布流(Firecrawl 灵魂,强烈推荐)

这是 Firecrawl 与普通爬虫框架的本质区别。若已有 Scrapling/Crawl4AI/BrowserUse 等多引擎抓取组件,天然适合改造成这个模式。

python 复制代码
# 伪代码:Python 版引擎瀑布流
ENGINES = [
    {"name": "cache",     "quality": 1000, "features": {...}},
    {"name": "crawl4ai",  "quality": 50,   "features": {"js": True, "actions": False}},
    {"name": "scrapling", "quality": 20,   "features": {"js": True}},
    {"name": "httpx",     "quality": 5,    "features": {"js": False}},
]

async def scrape(url, options):
    flags = build_feature_flags(url, options)      # 如需要 JS 渲染?
    candidates = [e for e in ENGINES
                  if support_score(e, flags) >= threshold]
    candidates.sort(key=lambda e: e["quality"], reverse=True)
    active = []
    while candidates:
        active.append(launch(next(candidates)))
        done = await asyncio.wait(active + [waterfall_timeout()],
                                  return_when=FIRST_COMPLETED)
        for task in done:
            result = task.result()
            if quality_ok(result):      # 内容非空 + 状态码 OK + 无错误
                return result
            active.remove(task)

要点

  • 质量评估三要素照搬:内容非空 + 2xx/304 + 无页面错误。不要只看状态码------200 但空页面是常见陷阱。
  • 瀑布流超时(不是串行 try/catch):引擎慢就让下一个引擎并行顶上,先到先得。实测能显著降低 P95。
  • Feature Flags:actions/screenshot/js/mobile 等决定哪些引擎可用。例如要截图就排除纯 HTTP 引擎。
  • 代理升级:403/429 自动换 stealth 模式重试(如 Scrapling StealthyFetcher 可作为 stealth 引擎)。
  • 缓存引擎 quality=1000 最先试:Redis 按 URL 缓存,命中直接返回(实测可带来数十倍加速)。

7.4 L3:Crawl 全站爬取

  • 队列 :先 Redis 即可(去重用 SET NX),规模大了再上 PostgreSQL/Celery。
  • 链接过滤链:12 步过滤照搬(excludes/includes 正则、深度、子域名、文件类型、robots.txt)。
  • URL 去重 :Redis crawl:{id}:url:{hash} NX 锁,24h TTL。
  • Map 端点:优先 sitemap.xml,回退爬页面提取链接。
  • 异步任务 + Webhook:jobId + 轮询 + webhook 通知。

7.5 L4:LLM 结构化提取(结合免费模型,性价比最高)

关键洞察 :Firecrawl 的 Extract 本质 = 抓取 + 一次 generateObject(JSON schema 约束输出)。用任何 OpenAI 兼容的免费/低成本模型即可复刻:

python 复制代码
# 伪代码:LLM 提取(OpenAI 兼容 + 免费模型)
import json
from openai import OpenAI

client = OpenAI(base_url="https://api.example.com/v1", api_key=KEY)  # 任意 OpenAI 兼容端点

def extract(urls, schema, prompt):
    docs = [scrape(u) for u in urls]          # 复用 L1/L2
    md = "\n\n---\n\n".join(d.markdown for d in docs)
    md = trim_to_tokens(md, max_tokens)        # tiktoken 精确截断
    resp = client.chat.completions.create(
        model="deepseek-v4-flash",
        response_format={"type": "json_object"},  # 或 json_schema
        messages=[
            {"role": "system", "content": build_system_prompt(schema)},
            {"role": "user", "content": f"{prompt}\n\n{md}"},
        ],
    )
    return validate_json(resp.choices[0].message.content, schema)

借鉴的细节

  • Schema 规范化 :字段全 required + additionalProperties: false(约束更严,输出更稳)。
  • 模型分级:简单 schema 用便宜模型,递归/复杂 schema 用贵模型(对应免费模型 → 付费模型分级)。
  • Token 截断 :先字符粗截(maxTokens×5),再 tiktoken 精截,最后 2.8 chars/token 兜底。
  • 重试降级:配额超限自动换备用模型(如智谱 glm-4-flash 可作 fallback)。
  • DeepSeek 等模型对 json_schema 支持差异 :用 json_object + 强 prompt 更稳(实测 deepseek 系列 schema 服从性优于 glm-4-flash)。

7.6 不建议照搬的部分(成本/复杂度陷阱)

Firecrawl 能力 建议 原因
Fire-engine 自研浏览器集群 ❌ 不学 需要大量 infra(浏览器池、代理池、状态同步),自托管版也没有;用 Playwright 池 + stealth 替代
FoundationDB 队列 ❌ 不学 超大规模才需要,Redis/PostgreSQL 够用
Engpicker AI 引擎选择(GPT 评估) ⚠️ 简化 思路很好但每次评估调 LLM 有成本;先做域名→引擎映射表 + 失败惩罚分(本地统计),成熟后再上 LLM 评估
Spark 自研模型 ❌ 不学 大模型是另一个领域
Go/Rust 混合 ⚠️ 按需 Python 生态用 markdownify/trafilatura 或子进程调 Go 库即可,不必一开始就搞 c-shared

7.7 推荐技术路线(Python 实现)

复制代码
阶段 0(地基):FastAPI 服务
  ├─ POST /v1/scrape {url, formats} → ScrapeEngine
  ├─ POST /v1/crawl {url, limit} → 队列 + 轮询
  └─ POST /v1/map {url} → sitemap + 链接提取

阶段 1(引擎层):
  ├─ 引擎注册表:httpx(fast) / Scrapling(medium) / Crawl4AI(js+md) / StealthyFetcher(反爬)
  ├─ 瀑布流调度器(asyncio + 质量评估 + 超时)
  ├─ 缓存引擎(Redis,quality 1000)
  └─ Transformers 管线(rawHtml → html → markdown → metadata → links)

阶段 2(Crawl + Map + 任务系统):
  ├─ Redis 队列 + 去重锁 + robots.txt 检查
  ├─ 链接过滤链(12 步)
  └─ Webhook 通知

阶段 3(LLM 提取,接免费模型):
  ├─ /v1/extract {urls, schema, prompt}
  ├─ schema 规范化 + tiktoken 截断 + json_object 输出
  └─ 模型分级:deepseek-v4-flash(默认)→ glm-4-flash(fallback)

阶段 4(可选增强):
  ├─ 域名→引擎经验表(简化版 Engpicker)
  ├─ 页面 diff 监控(Monitor 雏形)
  └─ 结构化提取模板(product/menu/attributes)

7.8 合规红线(Firecrawl 也在强调)

  • robots.txt 默认遵守(用户可配置跳过但要有默认)
  • 限速/礼貌抓取:单域名 QPS 限制,防止封 IP 和法律风险
  • 数据合规:PII 脱敏、完成后清理中间数据(ZDR 思想)
  • License 提醒 :Firecrawl 本身是 AGPL-3.0,若要商业化自研,不要直接抄它的代码(AGPL 传染),参考架构思路即可;SDK 层才是 MIT。走"借鉴思路、自研实现"路线最安全。

8. 附录:源码关键路径索引

路径 内容
apps/api/src/scraper/scrapeURL/index.ts scrapeURL 主入口(52KB,核心编排)
apps/api/src/scraper/scrapeURL/engines/index.ts 引擎瀑布流核心算法(引擎表 + feature flags + 调度)
apps/api/src/scraper/scrapeURL/engines/fetch/index.ts fetch 引擎(undici + 字符集处理)
apps/api/src/scraper/scrapeURL/engines/fire-engine/scrape.ts Fire-engine 客户端
apps/api/src/scraper/scrapeURL/engines/index/ index 缓存引擎
apps/api/src/scraper/scrapeURL/transformers/index.ts Transformers 管线编排
apps/api/src/scraper/scrapeURL/transformers/llmExtract.ts LLM 提取(54KB,模型选择/截断/重试)
apps/api/src/scraper/scrapeURL/transformers/agent.ts Agent transformer
apps/api/src/scraper/scrapeURL/lib/abortManager.ts 三级超时管理
apps/api/src/lib/engpicker.ts AI 引擎选择器
apps/api/src/lib/extract/fire-0/ 新一代 Agent 提取管线
apps/api/src/lib/html-to-markdown-client.ts Go 转换服务客户端
apps/api/sharedLibs/go-html-to-md/html-to-markdown.go Go HTML→MD(GFM + 代码块保护)
apps/api/src/lib/crawl-redis.ts Crawl Redis 状态
apps/api/src/services/index.ts 索引缓存服务
apps/api/src/lib/robots-txt.ts robots.txt 解析
apps/api/src/lib/threat-protection/ 威胁防护
apps/api/src/lib/keyless.ts 免密免费额度
apps/api/src/config.ts 全量配置项(zod schema,18830 字符)
docker-compose.yaml 自托管部署
examples/kubernetes/firecrawl-helm/ K8s Helm chart
apps/test-suite/ 评测套件(含 load-test)

附:参考资料

相关推荐
深蓝电商API6 小时前
Hook XMLHttpRequest 实战
爬虫·hook
quantdash_cc1 天前
告别自建 Requests/BS4 网页爬虫:基于 QuantDash 搭建零维保的高性能量化行情流水线
开发语言·爬虫·python·pandas·量化·quantdash
Patrick在香港1 天前
Python爬虫框架实战:优雅抓取香港政府公开API数据的通用方案
java·开发语言·爬虫·python·ai编程·数据可视化·可用性测试
鬼手点金2 天前
与LLM结合的主流智能爬虫框架
爬虫·python·llm·post·request·firecrawl·crawl4ai
天启HTTP3 天前
爬虫频繁弹验证码?解析网站反爬检测机制
网络·爬虫·tcp/ip
深蓝电商API3 天前
如何快速定位加密函数?
爬虫·加密函数
oh,huoyuyan4 天前
网页公开数据采集工具推荐
人工智能·爬虫·火车采集器
崔子末4 天前
某影视库剧集列表以及查询接口逆向
爬虫·python
雪山青木4 天前
全国微博签到数据201912-202004
大数据·爬虫·python·数据挖掘·数据分析·新浪微博