爬虫(Firecrawl)
概述
基于 Firecrawl 的网页数据采集技能。Firecrawl 是一个开源的网页抓取 API 服务,能够搜索网页、抓取单页、爬取整站、提取结构化数据,并将网页内容转换为 LLM 可用的 Markdown 或 JSON 格式。支持 JS 重度页面、自动代理轮换、速率限制处理等。
核心能力:
| 功能 | 说明 | 适用场景 | |------|------|---------| | Search | 搜索网页并返回完整页面内容 | 搜索引擎式信息检索 | | Scrape | 将任意 URL 转为 Markdown/HTML/截图/JSON | 单页内容采集 | | Crawl | 爬取整个网站的所有页面 | 全站数据采集 | | Map | 发现网站上所有 URL 链接 | 站点结构探测 | | Batch Scrape | 批量抓取多个 URL | 多页并行采集 | | Agent | AI 自主搜索并收集数据 | 不知道 URL 时的智能采集 | | Extract | 结构化数据提取(带 Schema) | 从网页提取特定字段 | | Interact | 抓取后用 AI 操控页面(点击/输入/滚动) | 需要交互的动态页面 |
前置条件
方式一:Cloud API(推荐,最简单)
- 前往 firecrawl.dev 注册账号
- 获取 API Key(格式:
fc-xxxx) - 安装 Python SDK:
pip install firecrawl-py
用户需提供 API Key。若用户未提供,询问:「请提供你的 Firecrawl API Key(可在 firecrawl.dev 获取)。如果没有,我可以指导你注册。」
方式二:自托管(适合隐私敏感场景)
参见 references/self-hosting.md。自托管无需 API Key,但功能受限(无 Fire-engine 高级反爬、无云端搜索)。
触发场景
当用户出现以下任意一种情况时使用本技能:
- 要求抓取/爬取/采集某个网页或网站的内容
- 要求将网页转为 Markdown
- 要求从网页中提取特定信息(价格、标题、联系人等)
- 要求搜索网页并获取正文内容
- 要求批量抓取多个 URL
- 要求发现某网站的所有链接
- 要求让 AI 自主上网搜索并收集数据
- 提到 Firecrawl、爬虫、网页抓取、数据采集
- 发送 URL 并要求获取其内容
工作流程
第 1 步:确认使用方式
检查用户是否提供了 API Key:
- 有 API Key → 使用 Cloud API(方式一)
- 无 API Key → 询问是否注册 Cloud API 或自托管
- 自托管 → 确认自托管服务地址(默认
http://localhost:3002)
第 2 步:安装 SDK(如未安装)
C:\Users\Administrator\.workbuddy\binaries\python\versions\3.13.12\python.exe -m venv C:\Users\Administrator\.workbuddy\binaries\python\envs\default
C:\Users\Administrator\.workbuddy\binaries\python\envs\default/Scripts/pip install firecrawl-py
若已安装过则跳过。
第 3 步:根据需求选择功能
根据用户需求选择对应功能,编写 Python 脚本执行。详见下方各功能的使用方法。
第 4 步:执行并返回结果
运行脚本,将采集结果整理后返回给用户。对于大量数据,保存为文件并使用 present_files 展示。
核心功能详解
1. Search — 搜索网页
搜索网页并返回完整页面内容(不只是摘要,而是整页 Markdown)。
from firecrawl import Firecrawl
app = Firecrawl(api_key="fc-YOUR_API_KEY")
# 基本搜索
result = app.search("best AI data tools 2024", limit=5)
# 搜索并获取 Markdown 内容
result = app.search(
"南京新房楼盘推荐",
limit=10,
sources=[{"type": "web"}],
)
# 遍历结果
for item in result.web:
print(f"标题: {item.title}")
print(f"URL: {item.url}")
# 如果配置了 scrapeOptions,还会有 markdown 内容
参数:
| 参数 | 类型 | 说明 |
|------|------|------|
| query | str | 搜索关键词(必填) |
| limit | int | 返回结果数(默认 5,最大 100) |
| sources | list | 数据源类型:web/news/images |
| scrape_options | dict | 抓取选项(如 formats) |
| include_domains | list | 只包含这些域名 |
| exclude_domains | list | 排除这些域名 |
2. Scrape — 抓取单页
将任意 URL 转换为 Markdown、HTML、截图或结构化 JSON。
from firecrawl import Firecrawl
app = Firecrawl(api_key="fc-YOUR_API_KEY")
# 基本抓取 — 获取 Markdown
doc = app.scrape("https://firecrawl.dev", formats=["markdown"])
print(doc.markdown)
# 抓取并提取结构化数据(使用 Pydantic Schema)
from pydantic import BaseModel, Field
from typing import Optional
class CompanyInfo(BaseModel):
company_mission: str = Field(description="公司使命")
supports_sso: bool = Field(description="是否支持 SSO")
is_open_source: bool = Field(description="是否开源")
result = app.scrape(
"https://firecrawl.dev",
formats=[{"type": "json", "schema": CompanyInfo}],
only_main_content=False
)
print(result.json)
# 抓取并提取(使用 prompt)
result = app.scrape(
"https://firecrawl.dev",
formats=[{"type": "json", "prompt": "提取公司使命和定价信息"}],
)
# 抓取多格式
doc = app.scrape(
"https://docs.firecrawl.dev",
formats=["markdown", "html"],
only_main_content=True, # 只取正文
max_age=600000, # 缓存 10 分钟内有效
)
参数:
| 参数 | 类型 | 说明 |
|------|------|------|
| url | str | 要抓取的 URL(必填) |
| formats | list | 输出格式:markdown/html/rawHtml/screenshot/links/json |
| only_main_content | bool | 只返回正文内容(默认 True) |
| max_age | int | 缓存有效期(毫秒) |
| timeout | int | 超时时间(毫秒) |
| location | dict | 地理位置:{"country": "US", "languages": ["en"]} |
| proxy | str | 代理设置:auto/basic/stealth |
| actions | list | 抓取前执行的浏览器动作(点击/滚动/输入等) |
3. Crawl — 爬取整站
爬取整个网站的所有页面,自动处理分页和子页面。
from firecrawl import Firecrawl
app = Firecrawl(api_key="fc-YOUR_API_KEY")
# 爬取整站(SDK 自动轮询等待完成)
docs = app.crawl(
url="https://docs.firecrawl.dev",
limit=50, # 最多爬取 50 页
scrape_options={
"formats": ["markdown"]
}
)
# 遍历所有页面
for doc in docs.data:
print(f"URL: {doc.metadata.source_url}")
print(f"内容前100字: {doc.markdown[:100]}")
print("---")
参数:
| 参数 | 类型 | 说明 |
|------|------|------|
| url | str | 起始 URL(必填) |
| limit | int | 最大爬取页数 |
| scrape_options | dict | 每页的抓取选项 |
| prompt | str | AI 引导爬取(描述想要什么内容) |
| webhook | str/dict | 完成后回调 URL |
4. Map — 发现网站链接
快速发现网站上的所有 URL,不需要实际抓取内容。
from firecrawl import Firecrawl
app = Firecrawl(api_key="fc-YOUR_API_KEY")
# 发现所有链接
result = app.map("https://firecrawl.dev", limit=50)
for link in result.links:
print(f"URL: {link.url}, 标题: {link.title}")
# 搜索特定链接
result = app.map(
"https://firecrawl.dev",
search="pricing", # 按相关性排序
sitemap="include", # 包含 sitemap
)
5. Batch Scrape — 批量抓取
同时抓取多个 URL,适合批量采集。
from firecrawl import Firecrawl
app = Firecrawl(api_key="fc-YOUR_API_KEY")
job = app.batch_scrape(
urls=[
"https://firecrawl.dev",
"https://docs.firecrawl.dev",
"https://firecrawl.dev/pricing"
],
formats=["markdown"],
poll_interval=2, # 轮询间隔(秒)
wait_timeout=120, # 最大等待时间(秒)
)
for doc in job.data:
print(f"URL: {doc.metadata.source_url}")
print(doc.markdown[:200])
6. Agent — AI 自主采集
描述你需要什么数据,AI 自主搜索、导航并获取。不需要提供 URL。
from firecrawl import Firecrawl
from pydantic import BaseModel, Field
from typing import List, Optional
app = Firecrawl(api_key="fc-YOUR_API_KEY")
# 基本使用 — 自然语言描述需求
result = app.agent(prompt="Find the pricing plans for Notion")
print(result.data.result)
print(result.data.sources)
# 结构化输出
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)
# 指定 URL 范围
result = app.agent(
urls=["https://docs.firecrawl.dev", "https://firecrawl.dev/pricing"],
prompt="Compare the features and pricing information"
)
# 选择模型
result = app.agent(
prompt="Compare enterprise features across Firecrawl, Apify, and ScrapingBee",
model="spark-1-pro" # spark-1-mini(默认,便宜)或 spark-1-pro(更强)
)
模型选择:
| 模型 | 特点 | 适用场景 |
|------|------|---------|
| spark-1-mini | 默认,成本低 60% | 大多数任务 |
| spark-1-pro | 标准价格 | 复杂研究、跨站对比、高精度需求 |
7. Extract — 结构化提取
从多个 URL 中提取结构化数据,支持 JSON Schema。
from firecrawl import Firecrawl
app = Firecrawl(api_key="fc-YOUR_API_KEY")
schema = {
"type": "object",
"properties": {
"title": {"type": "string"},
"price": {"type": "string"},
"description": {"type": "string"}
},
"required": ["title"]
}
result = app.extract(
urls=["https://example.com/product1", "https://example.com/product2"],
prompt="Extract product title, price, and description",
schema=schema,
)
print(result.data)
8. Interact — 页面交互
抓取页面后,用 AI 操控浏览器(点击、输入、滚动等)。
from firecrawl import Firecrawl
app = Firecrawl(api_key="fc-YOUR_API_KEY")
# 1. 先抓取页面
result = app.scrape("https://amazon.com")
scrape_id = result.metadata.scrape_id
# 2. 用 AI 操控页面
app.interact(scrape_id, prompt="Search for 'mechanical keyboard'")
app.interact(scrape_id, prompt="Click the first result")
# 3. 用代码操控页面(也支持)
app.interact(
scrape_id,
code="document.querySelector('#search').value = 'laptop'",
language="node"
)
常用工作流
工作流 A:搜索 + 抓取(最常用)
from firecrawl import Firecrawl
app = Firecrawl(api_key="fc-YOUR_API_KEY")
# 1. 搜索
results = app.search("2024年最好的开源AI项目", limit=5)
# 2. 逐个抓取详情
for item in results.web:
doc = app.scrape(item.url, formats=["markdown"], only_main_content=True)
print(f"=== {item.title} ===")
print(doc.markdown[:500])
工作流 B:整站爬取 + 保存文件
from firecrawl import Firecrawl
import json
app = Firecrawl(api_key="fc-YOUR_API_KEY")
# 爬取文档站
docs = app.crawl("https://docs.example.com", limit=100, scrape_options={"formats": ["markdown"]})
# 保存为 JSON
output = []
for doc in docs.data:
output.append({
"url": doc.metadata.source_url,
"title": doc.metadata.title if hasattr(doc.metadata, 'title') else "",
"markdown": doc.markdown
})
with open("crawled_data.json", "w", encoding="utf-8") as f:
json.dump(output, f, ensure_ascii=False, indent=2)
工作流 C:Agent 智能采集 + 结构化输出
from firecrawl import Firecrawl
from pydantic import BaseModel, Field
from typing import List
app = Firecrawl(api_key="fc-YOUR_API_KEY")
class ProductInfo(BaseModel):
name: str = Field(description="产品名称")
price: str = Field(description="价格")
features: List[str] = Field(description="主要特性")
class ProductList(BaseModel):
products: List[ProductInfo] = Field(description="产品列表")
result = app.agent(
prompt="Find all products and their pricing on stripe.com",
schema=ProductList,
model="spark-1-pro"
)
for product in result.data.products:
print(f"{product.name}: {product.price}")
cURL 方式(无需 Python SDK)
如果无法安装 Python SDK,可直接用 cURL 调用 API:
# 搜索
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}'
# 抓取单页
curl -X POST 'https://api.firecrawl.dev/v2/scrape' \
-H 'Authorization: Bearer fc-YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{"url": "https://firecrawl.dev"}'
# 爬取整站(异步,返回 job ID)
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}'
# 查询爬取状态
curl -X GET 'https://api.firecrawl.dev/v2/crawl/JOB_ID' \
-H 'Authorization: Bearer fc-YOUR_API_KEY'
# 发现链接
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"}'
自托管模式下,将 https://api.firecrawl.dev 替换为自托管地址(如 http://localhost:3002)。
注意事项
- API Key 安全:不要将 API Key 硬编码在脚本中,建议通过环境变量
FIRECRAWL_API_KEY传入 - 速率限制:Cloud API 有速率限制,批量操作时注意控制并发
- credits 消耗:每次抓取/爬取会消耗 credits,Crawl 按页面数计费
- 自托管限制:自托管版本无 Fire-engine 高级反爬能力,对 JS 重度页面支持有限
- 合法性:抓取数据时遵守目标网站的 robots.txt 和使用条款
- 输出处理:大量数据建议保存为文件后用 present_files 展示,避免直接输出到对话
微信扫一扫