GitCode 镜像地址:https://gitcode.com/GitHub_Trending/fi/firecrawl
GitHub 原始仓库:https://github.com/firecrawl/firecrawl
一、项目介绍
1.1 项目概述
Firecrawl 是一个开源的 Web 数据采集与处理平台,能够将整个网站转化为适用于大型语言模型(LLM)的 Markdown 格式或结构化 JSON 数据。它提供搜索、抓取、爬取和交互等核心能力,覆盖 96% 的网页内容(包括 JavaScript 重度渲染页面),P95 延迟仅 3.4 秒,专为实时 AI Agent 和动态应用设计。
项目采用 AGPL-3.0 开源协议(SDK 为 MIT 协议),以 TypeScript 为主要开发语言,同时提供云端托管服务和自托管两种使用方式。

图 1:Firecrawl 数据处理流水线 --- 从目标网站到 LLM 就绪输出
1.2 核心特性
| 特性 | 说明 |
|---|---|
| 行业领先的可靠性 | 覆盖 96% 的网页,包括 JS 重度渲染页面,无需自行管理代理 |
| 极速响应 | 跨数百万页面的 P95 延迟为 3.4 秒,适合实时 Agent 应用 |
| LLM 就绪输出 | 输出干净的 Markdown、结构化 JSON、截图等,减少 token 消耗 |
| 零配置基础设施 | 自动处理代理轮换、速率限制、JS 阻塞内容等复杂问题 |
| Agent 集成 | 通过单条命令将 Firecrawl 连接到任何 AI Agent 或 MCP 客户端 |
| 媒体解析 | 支持从网页托管的 PDF、DOCX 等文件中解析和提取内容 |
| 页面交互 | 支持在提取内容前执行点击、滚动、输入、等待、按键等操作 |
| 开源透明 | 社区驱动开发,代码完全开放 |
1.3 功能架构
Firecrawl 提供六大核心功能端点,覆盖从单页抓取到全站爬取、从关键词搜索到 AI 自主数据采集的完整场景:

图 2:Firecrawl 六大核心功能
各功能端点说明如下:
| 功能 | 端点 | 说明 |
|---|---|---|
| Search | /v2/search |
搜索网络并返回结果的完整页面内容 |
| Scrape | /v2/scrape |
将任意 URL 转换为 Markdown、HTML、截图或结构化 JSON |
| Interact | /v2/scrape/{id}/interact |
抓取页面后,通过 AI 提示或代码与页面交互 |
| Agent | /v2/agent |
描述需求,AI Agent 自主搜索、导航并获取数据 |
| Crawl | /v2/crawl |
通过单次请求抓取网站的所有 URL |
| Map | /v2/map |
即时发现网站上的所有 URL |
| Batch Scrape | --- | 异步批量抓取数千个 URL |
1.4 系统架构
Firecrawl 的自托管架构由以下核心组件构成:

图 3:Firecrawl 系统架构总览
#mermaid-svg-66TmcEe0YEr6nwVm{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-66TmcEe0YEr6nwVm .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-66TmcEe0YEr6nwVm .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-66TmcEe0YEr6nwVm .error-icon{fill:#552222;}#mermaid-svg-66TmcEe0YEr6nwVm .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-66TmcEe0YEr6nwVm .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-66TmcEe0YEr6nwVm .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-66TmcEe0YEr6nwVm .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-66TmcEe0YEr6nwVm .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-66TmcEe0YEr6nwVm .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-66TmcEe0YEr6nwVm .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-66TmcEe0YEr6nwVm .marker{fill:#333333;stroke:#333333;}#mermaid-svg-66TmcEe0YEr6nwVm .marker.cross{stroke:#333333;}#mermaid-svg-66TmcEe0YEr6nwVm svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-66TmcEe0YEr6nwVm p{margin:0;}#mermaid-svg-66TmcEe0YEr6nwVm .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-66TmcEe0YEr6nwVm .cluster-label text{fill:#333;}#mermaid-svg-66TmcEe0YEr6nwVm .cluster-label span{color:#333;}#mermaid-svg-66TmcEe0YEr6nwVm .cluster-label span p{background-color:transparent;}#mermaid-svg-66TmcEe0YEr6nwVm .label text,#mermaid-svg-66TmcEe0YEr6nwVm span{fill:#333;color:#333;}#mermaid-svg-66TmcEe0YEr6nwVm .node rect,#mermaid-svg-66TmcEe0YEr6nwVm .node circle,#mermaid-svg-66TmcEe0YEr6nwVm .node ellipse,#mermaid-svg-66TmcEe0YEr6nwVm .node polygon,#mermaid-svg-66TmcEe0YEr6nwVm .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-66TmcEe0YEr6nwVm .rough-node .label text,#mermaid-svg-66TmcEe0YEr6nwVm .node .label text,#mermaid-svg-66TmcEe0YEr6nwVm .image-shape .label,#mermaid-svg-66TmcEe0YEr6nwVm .icon-shape .label{text-anchor:middle;}#mermaid-svg-66TmcEe0YEr6nwVm .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-66TmcEe0YEr6nwVm .rough-node .label,#mermaid-svg-66TmcEe0YEr6nwVm .node .label,#mermaid-svg-66TmcEe0YEr6nwVm .image-shape .label,#mermaid-svg-66TmcEe0YEr6nwVm .icon-shape .label{text-align:center;}#mermaid-svg-66TmcEe0YEr6nwVm .node.clickable{cursor:pointer;}#mermaid-svg-66TmcEe0YEr6nwVm .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-66TmcEe0YEr6nwVm .arrowheadPath{fill:#333333;}#mermaid-svg-66TmcEe0YEr6nwVm .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-66TmcEe0YEr6nwVm .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-66TmcEe0YEr6nwVm .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-66TmcEe0YEr6nwVm .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-66TmcEe0YEr6nwVm .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-66TmcEe0YEr6nwVm .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-66TmcEe0YEr6nwVm .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-66TmcEe0YEr6nwVm .cluster text{fill:#333;}#mermaid-svg-66TmcEe0YEr6nwVm .cluster span{color:#333;}#mermaid-svg-66TmcEe0YEr6nwVm div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-66TmcEe0YEr6nwVm .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-66TmcEe0YEr6nwVm rect.text{fill:none;stroke-width:0;}#mermaid-svg-66TmcEe0YEr6nwVm .icon-shape,#mermaid-svg-66TmcEe0YEr6nwVm .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-66TmcEe0YEr6nwVm .icon-shape p,#mermaid-svg-66TmcEe0YEr6nwVm .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-66TmcEe0YEr6nwVm .icon-shape .label rect,#mermaid-svg-66TmcEe0YEr6nwVm .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-66TmcEe0YEr6nwVm .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-66TmcEe0YEr6nwVm .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-66TmcEe0YEr6nwVm :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} HTTP 请求
任务入队
状态存储
任务消费
JS 渲染
HTTP 抓取
结果返回
轮询结果
响应
格式化
客户端 / SDK / CLI
API Gateway :3002
Redis 队列
PostgreSQL
Worker 进程
Playwright 服务
目标网站
LLM 就绪输出
Markdown / JSON / 截图
各组件职责:
- API Gateway --- 接收所有 HTTP 请求,负责任务调度、结果返回和身份认证
- Worker 进程 --- 消费 Redis 队列中的任务,执行实际的网页抓取和数据处理
- Playwright 服务 --- 处理需要 JavaScript 渲染的动态页面
- Redis --- 任务队列和速率限制
- PostgreSQL --- 持久化存储任务状态和元数据
1.5 适用场景
- RAG 知识库构建 --- 将文档站点、博客等内容批量转换为 Markdown,为 LLM 提供高质量上下文
- AI Agent 数据采集 --- 让 Agent 自主搜索网络、提取结构化数据,无需预先知道 URL
- 竞品监控 --- 定期抓取竞品网站的价格、功能等信息
- 数据集构建 --- 大规模采集网页内容用于训练或微调模型
- 内容迁移 --- 将旧网站内容提取为结构化数据用于迁移
二、安装说明
Firecrawl 提供四种使用方式,按推荐程度排列如下。
2.1 方式一:使用 Firecrawl 云服务(推荐快速上手)
无需安装任何基础设施,注册即可使用。
- 访问 firecrawl.dev 注册账号
- 在控制台获取 API Key(格式为
fc-YOUR_API_KEY) - 可在 Playground 中在线测试各功能
获取 API Key 后,即可通过 SDK、CLI 或直接调用 REST API 开始使用。
2.2 方式二:安装 SDK
Python SDK
bash
pip install firecrawl-py
Node.js SDK
bash
npm install firecrawl
SDK 会自动处理异步操作的轮询逻辑,开发者无需手动检查任务状态。
2.3 方式三:自托管部署(Docker Compose)
适用于需要数据留在自有基础设施内、或需要定制化服务的场景。
前置条件
- Git
- Docker Engine 或 Docker Desktop
- Docker Compose v2(通过
docker compose命令调用) curl(用于验证请求)- 确保端口
3002可用
步骤一:克隆仓库
以下命令以 v2.11.162 版本为例(该版本经过验证):
bash
git clone https://github.com/firecrawl/firecrawl.git
cd firecrawl
git checkout v2.11.162
如使用 GitCode 镜像加速,可将克隆地址替换为:
git clone https://gitcode.com/GitHub_Trending/fi/firecrawl.git
步骤二:配置环境变量
在仓库根目录创建 .env 文件:
bash
cat > .env <<'EOF'
# ===== 必填项 =====
PORT=3002
HOST=0.0.0.0
USE_DB_AUTHENTICATION=false
# ===== PostgreSQL 配置 =====
POSTGRES_USER=postgres
POSTGRES_PASSWORD=替换为至少32位随机字符
POSTGRES_DB=postgres
# ===== 队列管理面板密钥(部署到服务器时务必修改)=====
BULL_AUTH_KEY=CHANGEME
# ===== 可选:AI 功能 =====
# OPENAI_API_KEY=
# 实验性:使用 Ollama
# OLLAMA_BASE_URL=http://localhost:11434/api
# MODEL_NAME=deepseek-r1:7b
# ===== 可选:代理配置 =====
# PROXY_SERVER=
# PROXY_USERNAME=
# PROXY_PASSWORD=
# ===== 可选:搜索引擎 =====
# SEARXNG_ENDPOINT=http://your.searxng.server
EOF
安全注意事项:
- 生产环境务必设置强 PostgreSQL 密码,不要使用默认值
- 不要将 PostgreSQL 端口暴露到公网
- 将
BULL_AUTH_KEY设置为强随机密钥 - 不要将
.env文件提交到版本控制
步骤三:构建并启动
bash
docker compose up --build -d
docker compose ps --all
注意使用
docker compose(带空格)而非docker-compose。
启动后,API 服务可通过 http://localhost:3002 访问。
步骤四:验证服务
检查 API 健康状态:
bash
curl \
--fail \
--silent \
--show-error \
--max-time 5 \
http://localhost:3002/v0/health/readiness
预期返回:
json
{"status":"ok"}
执行一次实际抓取测试:
bash
curl \
--fail-with-body \
--silent \
--show-error \
--max-time 75 \
-X POST \
http://localhost:3002/v2/scrape \
-H 'Content-Type: application/json' \
-d '{
"url": "https://example.com",
"formats": ["markdown"],
"timeout": 60000
}'
成功响应格式:
json
{
"success": true,
"data": {
"markdown": "...",
"metadata": {
"statusCode": 200
}
}
}
自托管功能支持矩阵
| 需求 | 自托管是否支持 |
|---|---|
| 核心抓取、爬取、Map、搜索 | 支持(Fetch + Playwright) |
| LLM 支持的结构化提取 | 需配置 OpenAI 兼容提供者或 Ollama |
| Fire-engine 高级反爬 | 不包含,需单独配置 |
| 截图和页面操作 | 默认不支持,需 Fire-engine |
| Agent、Browser、Interact | 建议使用 Firecrawl Cloud |
2.4 方式四:Kubernetes 部署
Firecrawl 提供两种 Kubernetes 部署方式:
简易版部署:
参考仓库中的 examples/kubernetes/cluster-install/README.md。
Helm 部署:
参考仓库中的 examples/kubernetes/firecrawl-helm/README.md。
2.5 安装 CLI 工具
Firecrawl CLI 提供命令行交互能力,无需编写代码即可使用全部功能:
bash
# 使用 npx 直接运行(无需安装)
npx -y firecrawl-cli@latest --help
# 为 AI Agent 安装 Firecrawl Skill 和 CLI
npx -y firecrawl-cli@latest init --all --browser
安装完成后重启 Agent 即可使用,支持 Claude Code、Antigravity、OpenCode 等客户端。
三、使用说明
3.1 快速开始
无论使用哪种方式,核心流程都是:获取 API Key → 调用 API → 获取结果。
#mermaid-svg-0WTXuc4S5vD0Rusm{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-0WTXuc4S5vD0Rusm .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-0WTXuc4S5vD0Rusm .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-0WTXuc4S5vD0Rusm .error-icon{fill:#552222;}#mermaid-svg-0WTXuc4S5vD0Rusm .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-0WTXuc4S5vD0Rusm .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-0WTXuc4S5vD0Rusm .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-0WTXuc4S5vD0Rusm .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-0WTXuc4S5vD0Rusm .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-0WTXuc4S5vD0Rusm .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-0WTXuc4S5vD0Rusm .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-0WTXuc4S5vD0Rusm .marker{fill:#333333;stroke:#333333;}#mermaid-svg-0WTXuc4S5vD0Rusm .marker.cross{stroke:#333333;}#mermaid-svg-0WTXuc4S5vD0Rusm svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-0WTXuc4S5vD0Rusm p{margin:0;}#mermaid-svg-0WTXuc4S5vD0Rusm .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-0WTXuc4S5vD0Rusm .cluster-label text{fill:#333;}#mermaid-svg-0WTXuc4S5vD0Rusm .cluster-label span{color:#333;}#mermaid-svg-0WTXuc4S5vD0Rusm .cluster-label span p{background-color:transparent;}#mermaid-svg-0WTXuc4S5vD0Rusm .label text,#mermaid-svg-0WTXuc4S5vD0Rusm span{fill:#333;color:#333;}#mermaid-svg-0WTXuc4S5vD0Rusm .node rect,#mermaid-svg-0WTXuc4S5vD0Rusm .node circle,#mermaid-svg-0WTXuc4S5vD0Rusm .node ellipse,#mermaid-svg-0WTXuc4S5vD0Rusm .node polygon,#mermaid-svg-0WTXuc4S5vD0Rusm .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-0WTXuc4S5vD0Rusm .rough-node .label text,#mermaid-svg-0WTXuc4S5vD0Rusm .node .label text,#mermaid-svg-0WTXuc4S5vD0Rusm .image-shape .label,#mermaid-svg-0WTXuc4S5vD0Rusm .icon-shape .label{text-anchor:middle;}#mermaid-svg-0WTXuc4S5vD0Rusm .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-0WTXuc4S5vD0Rusm .rough-node .label,#mermaid-svg-0WTXuc4S5vD0Rusm .node .label,#mermaid-svg-0WTXuc4S5vD0Rusm .image-shape .label,#mermaid-svg-0WTXuc4S5vD0Rusm .icon-shape .label{text-align:center;}#mermaid-svg-0WTXuc4S5vD0Rusm .node.clickable{cursor:pointer;}#mermaid-svg-0WTXuc4S5vD0Rusm .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-0WTXuc4S5vD0Rusm .arrowheadPath{fill:#333333;}#mermaid-svg-0WTXuc4S5vD0Rusm .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-0WTXuc4S5vD0Rusm .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-0WTXuc4S5vD0Rusm .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-0WTXuc4S5vD0Rusm .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-0WTXuc4S5vD0Rusm .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-0WTXuc4S5vD0Rusm .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-0WTXuc4S5vD0Rusm .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-0WTXuc4S5vD0Rusm .cluster text{fill:#333;}#mermaid-svg-0WTXuc4S5vD0Rusm .cluster span{color:#333;}#mermaid-svg-0WTXuc4S5vD0Rusm div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-0WTXuc4S5vD0Rusm .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-0WTXuc4S5vD0Rusm rect.text{fill:none;stroke-width:0;}#mermaid-svg-0WTXuc4S5vD0Rusm .icon-shape,#mermaid-svg-0WTXuc4S5vD0Rusm .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-0WTXuc4S5vD0Rusm .icon-shape p,#mermaid-svg-0WTXuc4S5vD0Rusm .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-0WTXuc4S5vD0Rusm .icon-shape .label rect,#mermaid-svg-0WTXuc4S5vD0Rusm .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-0WTXuc4S5vD0Rusm .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-0WTXuc4S5vD0Rusm .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-0WTXuc4S5vD0Rusm :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 注册获取 API Key
选择调用方式
SDK
CLI
REST API
处理返回结果
Markdown / JSON / 截图
3.2 Search --- 网络搜索
搜索网络并返回结果的完整页面内容。
Python:
python
from firecrawl import Firecrawl
app = Firecrawl(api_key="fc-YOUR_API_KEY")
search_result = app.search("firecrawl", limit=5)
for result in search_result:
print(result["title"])
print(result["url"])
print(result["markdown"][:200])
Node.js:
javascript
import { Firecrawl } from 'firecrawl';
const app = new Firecrawl({ apiKey: "fc-YOUR_API_KEY" });
const results = await app.search("firecrawl", { limit: 5 });
cURL:
bash
curl -X POST 'https://api.firecrawl.dev/v2/search' \
-H 'Authorization: Bearer fc-YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"query": "firecrawl",
"limit": 5
}'
CLI:
bash
firecrawl search "firecrawl" --limit 5
返回结果示例:
json
[
{
"url": "https://firecrawl.dev",
"title": "Firecrawl",
"markdown": "Turn websites into..."
},
{
"url": "https://docs.firecrawl.dev",
"title": "Firecrawl Docs",
"markdown": "# Getting Started..."
}
]
3.3 Scrape --- 单页抓取
将任意 URL 转换为 Markdown、HTML、截图或结构化 JSON。
基础用法:
python
from firecrawl import Firecrawl
app = Firecrawl(api_key="fc-YOUR_API_KEY")
result = app.scrape('https://firecrawl.dev')
print(result.markdown)
CLI 快捷方式:
bash
# 抓取并输出 Markdown
firecrawl scrape https://firecrawl.dev
# 仅提取主要内容(去除导航、广告等)
firecrawl https://firecrawl.dev --only-main-content
返回的 Markdown 示例:
markdown
# Firecrawl
Firecrawl helps AI agents search, scrape, and interact with the web.
## Features
- Search: Find information across the web
- Scrape: Clean data from any page
- Interact: Click, navigate, and operate pages
- Agent: Autonomous data gathering
结构化数据提取:
通过定义 JSON Schema,可以从页面中提取特定结构化数据:
python
from firecrawl import Firecrawl
from pydantic import BaseModel, Field
from typing import List, Optional
app = Firecrawl(api_key="fc-YOUR_API_KEY")
class Founder(BaseModel):
name: str = Field(description="创始人全名")
role: Optional[str] = Field(None, description="职位")
class FoundersSchema(BaseModel):
founders: List[Founder] = Field(description="创始人列表")
result = app.scrape(
"https://firecrawl.dev",
formats=["json"],
json_options=FoundersSchema
)
print(result.data)
3.4 Crawl --- 全站爬取
通过单次请求抓取整个网站的所有页面。这是一个异步操作,返回任务 ID。
发起爬取:
bash
curl -X POST 'https://api.firecrawl.dev/v2/crawl' \
-H 'Authorization: Bearer fc-YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"url": "https://docs.firecrawl.dev",
"limit": 100,
"scrapeOptions": {
"formats": ["markdown"]
}
}'
返回任务 ID:
json
{
"success": true,
"id": "123-456-789",
"url": "https://api.firecrawl.dev/v2/crawl/123-456-789"
}
检查爬取状态:
bash
curl -X GET 'https://api.firecrawl.dev/v2/crawl/123-456-789' \
-H 'Authorization: Bearer fc-YOUR_API_KEY'
json
{
"status": "completed",
"total": 50,
"completed": 50,
"creditsUsed": 50,
"data": [
{
"markdown": "# Page Title\n\nContent...",
"metadata": {
"title": "Page Title",
"sourceURL": "https://..."
}
}
]
}
使用 SDK 时,轮询逻辑会自动处理,开发者只需等待结果返回即可。
Python SDK 全站爬取示例:
python
from firecrawl import Firecrawl
app = Firecrawl(api_key="fc-YOUR_API_KEY")
# 自动等待爬取完成
docs = app.crawl("https://docs.firecrawl.dev", limit=50)
for doc in docs.data:
print(doc.metadata.source_url, doc.markdown[:100])
3.5 Map --- 站点 URL 发现
即时发现网站上的所有 URL,无需实际抓取页面内容。
bash
curl -X POST 'https://api.firecrawl.dev/v2/map' \
-H 'Authorization: Bearer fc-YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{"url": "https://firecrawl.dev"}'
返回结果:
json
{
"success": true,
"links": [
{"url": "https://firecrawl.dev", "title": "Firecrawl", "description": "Turn websites into LLM-ready data"},
{"url": "https://firecrawl.dev/pricing", "title": "Pricing", "description": "Firecrawl pricing plans"},
{"url": "https://firecrawl.dev/blog", "title": "Blog", "description": "Firecrawl blog"}
]
}
按关键词搜索站点内 URL:
python
from firecrawl import Firecrawl
app = Firecrawl(api_key="fc-YOUR_API_KEY")
result = app.map("https://firecrawl.dev", search="pricing")
# 返回与 "pricing" 相关度排序的 URL 列表
3.6 Agent --- AI 自主数据采集
描述你需要什么数据,AI Agent 会自主搜索、导航并获取结果,无需提供 URL。
#mermaid-svg-87DymsbFk4Tp5DqN{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-87DymsbFk4Tp5DqN .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-87DymsbFk4Tp5DqN .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-87DymsbFk4Tp5DqN .error-icon{fill:#552222;}#mermaid-svg-87DymsbFk4Tp5DqN .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-87DymsbFk4Tp5DqN .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-87DymsbFk4Tp5DqN .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-87DymsbFk4Tp5DqN .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-87DymsbFk4Tp5DqN .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-87DymsbFk4Tp5DqN .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-87DymsbFk4Tp5DqN .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-87DymsbFk4Tp5DqN .marker{fill:#333333;stroke:#333333;}#mermaid-svg-87DymsbFk4Tp5DqN .marker.cross{stroke:#333333;}#mermaid-svg-87DymsbFk4Tp5DqN svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-87DymsbFk4Tp5DqN p{margin:0;}#mermaid-svg-87DymsbFk4Tp5DqN .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-87DymsbFk4Tp5DqN .cluster-label text{fill:#333;}#mermaid-svg-87DymsbFk4Tp5DqN .cluster-label span{color:#333;}#mermaid-svg-87DymsbFk4Tp5DqN .cluster-label span p{background-color:transparent;}#mermaid-svg-87DymsbFk4Tp5DqN .label text,#mermaid-svg-87DymsbFk4Tp5DqN span{fill:#333;color:#333;}#mermaid-svg-87DymsbFk4Tp5DqN .node rect,#mermaid-svg-87DymsbFk4Tp5DqN .node circle,#mermaid-svg-87DymsbFk4Tp5DqN .node ellipse,#mermaid-svg-87DymsbFk4Tp5DqN .node polygon,#mermaid-svg-87DymsbFk4Tp5DqN .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-87DymsbFk4Tp5DqN .rough-node .label text,#mermaid-svg-87DymsbFk4Tp5DqN .node .label text,#mermaid-svg-87DymsbFk4Tp5DqN .image-shape .label,#mermaid-svg-87DymsbFk4Tp5DqN .icon-shape .label{text-anchor:middle;}#mermaid-svg-87DymsbFk4Tp5DqN .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-87DymsbFk4Tp5DqN .rough-node .label,#mermaid-svg-87DymsbFk4Tp5DqN .node .label,#mermaid-svg-87DymsbFk4Tp5DqN .image-shape .label,#mermaid-svg-87DymsbFk4Tp5DqN .icon-shape .label{text-align:center;}#mermaid-svg-87DymsbFk4Tp5DqN .node.clickable{cursor:pointer;}#mermaid-svg-87DymsbFk4Tp5DqN .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-87DymsbFk4Tp5DqN .arrowheadPath{fill:#333333;}#mermaid-svg-87DymsbFk4Tp5DqN .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-87DymsbFk4Tp5DqN .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-87DymsbFk4Tp5DqN .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-87DymsbFk4Tp5DqN .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-87DymsbFk4Tp5DqN .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-87DymsbFk4Tp5DqN .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-87DymsbFk4Tp5DqN .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-87DymsbFk4Tp5DqN .cluster text{fill:#333;}#mermaid-svg-87DymsbFk4Tp5DqN .cluster span{color:#333;}#mermaid-svg-87DymsbFk4Tp5DqN div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-87DymsbFk4Tp5DqN .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-87DymsbFk4Tp5DqN rect.text{fill:none;stroke-width:0;}#mermaid-svg-87DymsbFk4Tp5DqN .icon-shape,#mermaid-svg-87DymsbFk4Tp5DqN .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-87DymsbFk4Tp5DqN .icon-shape p,#mermaid-svg-87DymsbFk4Tp5DqN .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-87DymsbFk4Tp5DqN .icon-shape .label rect,#mermaid-svg-87DymsbFk4Tp5DqN .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-87DymsbFk4Tp5DqN .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-87DymsbFk4Tp5DqN .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-87DymsbFk4Tp5DqN :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 用户描述需求
Agent 自主搜索
导航目标页面
提取结构化数据
返回结果 + 来源
基本用法:
bash
curl -X POST 'https://api.firecrawl.dev/v2/agent' \
-H 'Authorization: Bearer fc-YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"prompt": "Find the pricing plans for Notion"
}'
响应:
json
{
"success": true,
"data": {
"result": "Notion offers the following pricing plans:\n\n1. Free - $0/month...\n2. Plus - $10/seat/month...\n3. Business - $18/seat/month...",
"sources": ["https://www.notion.so/pricing"]
}
}
结构化输出:
python
from firecrawl import Firecrawl
from pydantic import BaseModel, Field
from typing import List, Optional
app = Firecrawl(api_key="fc-YOUR_API_KEY")
class Founder(BaseModel):
name: str = Field(description="创始人全名")
role: Optional[str] = Field(None, description="职位")
class FoundersSchema(BaseModel):
founders: List[Founder] = Field(description="创始人列表")
result = app.agent(
prompt="Find the founders of Firecrawl",
schema=FoundersSchema
)
print(result.data)
输出:
json
{
"founders": [
{"name": "Eric Ciarla", "role": "Co-founder"},
{"name": "Nicolas Camara", "role": "Co-founder"},
{"name": "Caleb Peffer", "role": "Co-founder"}
]
}
指定 URL 范围:
python
result = app.agent(
urls=["https://docs.firecrawl.dev", "https://firecrawl.dev/pricing"],
prompt="Compare the features and pricing information"
)
模型选择:
| 模型 | 成本 | 适用场景 |
|---|---|---|
spark-1-mini(默认) |
低 60% | 大多数任务 |
spark-1-pro |
标准 | 复杂研究、关键数据采集 |
python
result = app.agent(
prompt="Compare enterprise features across Firecrawl, Apify, and ScrapingBee",
model="spark-1-pro"
)
建议使用 Pro 模型的场景:
- 跨多个网站比较数据
- 从具有复杂导航或需要认证的站点提取
- Agent 需要探索多条路径的研究任务
- 准确性至关重要的关键数据
3.7 Interact --- 页面交互
抓取页面后,通过 AI 提示或代码与页面进行交互(点击、输入、导航等)。
python
from firecrawl import Firecrawl
app = Firecrawl(api_key="fc-YOUR_API_KEY")
# 第一步:抓取页面
result = app.scrape("https://amazon.com")
scrape_id = result.metadata.scrape_id
# 第二步:通过自然语言指令与页面交互
app.interact(scrape_id, prompt="Search for 'mechanical keyboard'")
app.interact(scrape_id, prompt="Click the first result")
CLI 方式:
bash
firecrawl scrape https://amazon.com
firecrawl interact exec --prompt "Search for 'mechanical keyboard'"
firecrawl interact exec --prompt "Click the first result"
返回结果:
json
{
"success": true,
"output": "Keyboard available at $100",
"liveViewUrl": "https://liveview.firecrawl.dev/..."
}
3.8 Batch Scrape --- 批量抓取
异步批量抓取多个 URL:
python
from firecrawl import Firecrawl
app = Firecrawl(api_key="fc-YOUR_API_KEY")
job = app.batch_scrape([
"https://firecrawl.dev",
"https://docs.firecrawl.dev",
"https://firecrawl.dev/pricing"
], formats=["markdown"])
for doc in job.data:
print(doc.metadata.source_url)
print(doc.markdown[:100])
3.9 SDK 完整使用示例
以下是 Python SDK 的完整使用示例,涵盖所有核心功能:
python
from firecrawl import Firecrawl
app = Firecrawl(api_key="fc-YOUR_API_KEY")
# 1. 抓取单个 URL
doc = app.scrape("https://firecrawl.dev", formats=["markdown"])
print(doc.markdown)
# 2. AI Agent 自主数据采集
result = app.agent(prompt="Find the founders of Stripe")
print(result.data)
# 3. 全站爬取(自动等待完成)
docs = app.crawl("https://docs.firecrawl.dev", limit=50)
for doc in docs.data:
print(doc.metadata.source_url, doc.markdown[:100])
# 4. 网络搜索
results = app.search("best AI data tools 2024", limit=10)
print(results)
Node.js SDK 完整示例:
javascript
import { Firecrawl } from 'firecrawl';
const app = new Firecrawl({ apiKey: 'fc-YOUR_API_KEY' });
// 1. 抓取单个 URL
const doc = await app.scrape('https://firecrawl.dev', { formats: ['markdown'] });
console.log(doc.markdown);
// 2. AI Agent 自主数据采集
const result = await app.agent({ prompt: 'Find the founders of Stripe' });
console.log(result.data);
// 3. 全站爬取(自动等待完成)
const docs = await app.crawl('https://docs.firecrawl.dev', { limit: 50 });
docs.data.forEach(doc => {
console.log(doc.metadata.sourceURL, doc.markdown.substring(0, 100));
});
// 4. 网络搜索
const results = await app.search('best AI data tools 2024', { limit: 10 });
3.10 MCP 集成
将 Firecrawl 连接到任何兼容 MCP 的客户端(如 Claude Desktop):
json
{
"mcpServers": {
"firecrawl-mcp": {
"command": "npx",
"args": ["-y", "firecrawl-mcp"],
"env": {
"FIRECRAWL_API_KEY": "fc-YOUR_API_KEY"
}
}
}
}
MCP 服务器的详细文档参见 firecrawl-mcp-server。
3.11 自托管实例的 SDK 连接
使用自托管实例时,API Key 为可选项(仅在连接云服务时必需)。SDK 支持指定自定义 API 地址:
python
from firecrawl import Firecrawl
# 连接到自托管实例
app = Firecrawl(
api_url="http://localhost:3002",
api_key="" # 自托管模式下可选
)
3.12 常见问题排查
自托管:Supabase 客户端未配置
ERROR - Attempted to access Supabase client when it's not configured.
这是预期行为。自托管实例不支持配置 Supabase,但抓取和爬取功能可正常使用。
自托管:认证绕过警告
WARN - You're bypassing authentication
当 USE_DB_AUTHENTICATION=false 时出现此警告,属于正常的首次运行状态。请求使用自托管身份,无需 API Key。
Docker 容器启动失败
bash
# 检查容器状态和日志
docker compose ps --all
docker compose logs --tail=200
- 确保
.env文件中所有必需变量已正确设置 - 确保 Docker 有足够的 CPU、内存和磁盘资源
Redis 连接问题
确保 Redis 服务地址为 redis://redis:6379(Compose 网络内部地址),而非 localhost。
bash
docker compose ps redis
docker compose logs --tail=100 redis
API 端点无响应
bash
docker compose ps api
docker compose logs --tail=200 api
- 检查端口 3002 是否被其他进程占用
- 确认 API 容器状态为 running 后再重试