mcpField
F
firecrawl-scraper

firecrawl-scraper

github.com/jackspace数据与数据库16114 次安装13 周前更新
代码仓库

关于 firecrawl-scraper

介绍如何使用 Firecrawl 网页数据 API,将网页和整站内容转为 Markdown 或结构化数据的技能。涵盖页面抓取、站点爬取、URL 发现、数据提取和抓取前的浏览器操作,适合构建 LLM 网页数据处理流程的开发者。

主要功能

  1. 01抓取单个页面
  2. 02爬取多页网站
  3. 03发现站点 URL
  4. 04按定义的模式提取数据
  5. 05输出 Markdown、HTML 或截图
  6. 06抓取前执行浏览器操作

适用场景

  1. 01将文档网站转为 Markdown
  2. 02收集结构化商品信息
  3. 03提取整洁的新闻文章内容
  4. 04为 RAG 系统准备网站内容

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/jackspace/claudeskillz --skill firecrawl-scraper

安装后在 Claude Code 中输入/firecrawl-scraper确认已加载。

附带文件README.mdSKILL.json

详细介绍

Firecrawl 网页抓取工具

状态:已可投入生产 ✅ 最后更新:2025-10-24 官方文档:https://docs.firecrawl.dev API 版本:v2


什么是 Firecrawl?

Firecrawl 是一款面向 AI 的网页数据 API,可将整个网站转换为适用于大模型的 Markdown 或结构化数据。它支持:

  • JavaScript 渲染 - 执行客户端 JavaScript,以捕获动态内容
  • 绕过反机器人机制 - 绕过 CAPTCHA 和机器人检测系统
  • 格式转换 - 输出为 Markdown、JSON 或结构化数据
  • 截图捕获 - 保存网页的可视化表示
  • 浏览器自动化 - 提供完整的无头浏览器功能

API 端点

1. /v2/scrape - 抓取单个页面

抓取单个网页并返回干净、结构化的内容。

使用场景:

  • 提取文章内容
  • 获取产品详情
  • 抓取指定页面
  • 将 HTML 转换为 Markdown

主要选项:

  • formats:["markdown", "html", "screenshot"]
  • onlyMainContent:true/false(移除导航栏、页脚和广告)
  • waitFor:抓取前等待的毫秒数
  • actions:浏览器自动化操作(点击、滚动等)
2. /v2/crawl - 抓取整个网站

从起始 URL 开始,抓取所有可访问的页面。

使用场景:

  • 为整个文档网站建立索引
  • 归档网站内容
  • 构建知识库
  • 抓取多页内容

主要选项:

  • limit:抓取的页面数量上限
  • maxDepth:跟进链接的最大深度
  • allowedDomains:限制为指定域名
  • excludePaths:跳过特定 URL 模式
3. /v2/map - 发现 URL

列出网站上的所有 URL,不抓取页面内容。

使用场景:

  • 查找站点地图
  • 发现所有页面
  • 制定抓取策略
  • 审核网站结构
4. /v2/extract - 提取结构化数据

使用 AI 从页面中提取指定的数据字段。

使用场景:

  • 提取产品价格和名称
  • 解析联系信息
  • 构建结构化数据集
  • 自定义数据架构

主要选项:

  • schema:定义所需结构的 Zod 或 JSON 架构
  • systemPrompt:引导 AI 的提取行为

身份验证

所有 Firecrawl 请求都需要 API 密钥。

获取 API 密钥
  1. 在 https://www.firecrawl.dev 注册
  2. 前往控制面板 → API Keys
  3. 复制 API 密钥(以 fc- 开头)
安全存储

切勿在代码中硬编码 API 密钥!

# .env file
FIRECRAWL_API_KEY=fc-your-api-key-here
# .env.local (for local development)
FIRECRAWL_API_KEY=fc-your-api-key-here

Python SDK 用法

安装
pip install firecrawl-py

最新版本:firecrawl-py v4.5.0+

基本抓取
import os
from firecrawl import FirecrawlApp

# Initialize client
app = FirecrawlApp(api_key=os.environ.get("FIRECRAWL_API_KEY"))

# Scrape a single page
result = app.scrape_url(
    url="https://example.com/article",
    params={
        "formats": ["markdown", "html"],
        "onlyMainContent": True
    }
)

# Access markdown content
markdown = result.get("markdown")
print(markdown)
抓取多个页面
import os
from firecrawl import FirecrawlApp

app = FirecrawlApp(api_key=os.environ.get("FIRECRAWL_API_KEY"))

# Start crawl
crawl_result = app.crawl_url(
    url="https://docs.example.com",
    params={
        "limit": 100,
        "scrapeOptions": {
            "formats": ["markdown"]
        }
    },
    poll_interval=5  # Check status every 5 seconds
)

# Process results
for page in crawl_result.get("data", []):
    url = page.get("url")
    markdown = page.get("markdown")
    print(f"Scraped: {url}")
提取结构化数据
import os
from firecrawl import FirecrawlApp

app = FirecrawlApp(api_key=os.environ.get("FIRECRAWL_API_KEY"))

# Define schema
schema = {
    "type": "object",
    "properties": {
        "company_name": {"type": "string"},
        "product_price": {"type": "number"},
        "availability": {"type": "string"}
    },
    "required": ["company_name", "product_price"]
}

# Extract data
result = app.extract(
    urls=["https://example.com/product"],
    params={
        "schema": schema,
        "systemPrompt": "Extract product information from the page"
    }
)

print(result)

TypeScript/Node.js SDK 用法

安装
npm install @mendable/firecrawl-js
# or
pnpm add @mendable/firecrawl-js
# or use the unscoped package:
npm install firecrawl

最新版本:@mendable/firecrawl-js v4.4.1+(或 firecrawl v4.4.1+)

基本抓取
import FirecrawlApp from '@mendable/firecrawl-js';

// Initialize client
const app = new FirecrawlApp({
  apiKey: process.env.FIRECRAWL_API_KEY
});

// Scrape a single page
const result = await app.scrapeUrl('https://example.com/article', {
  formats: ['markdown', 'html'],
  onlyMainContent: true
});

// Access markdown content
const markdown = result.markdown;
console.log(markdown);
抓取多个页面
import FirecrawlApp from '@mendable/firecrawl-js';

const app = new FirecrawlApp({
  apiKey: process.env.FIRECRAWL_API_KEY
});

// Start crawl
const crawlResult = await app.crawlUrl('https://docs.example.com', {
  limit: 100,
  scrapeOptions: {
    formats: ['markdown']
  }
});

// Process results
for (const page of crawlResult.data) {
  console.log(`Scraped: ${page.url}`);
  console.log(page.markdown);
}
使用 Zod 提取结构化数据
import FirecrawlApp from '@mendable/firecrawl-js';
import { z } from 'zod';

const app = new FirecrawlApp({
  apiKey: process.env.FIRECRAWL_API_KEY
});

// Define schema with Zod
const schema = z.object({
  company_name: z.string(),
  product_price: z.number(),
  availability: z.string()
});

// Extract data
const result = await app.extract({
  urls: ['https://example.com/product'],
  schema: schema,
  systemPrompt: 'Extract product information from the page'
});

console.log(result);

常见使用场景

1. 抓取文档

场景:将整个文档网站转换为 Markdown,用于 RAG/聊天机器人

app = FirecrawlApp(api_key=os.environ.get("FIRECRAWL_API_KEY"))

docs = app.crawl_url(
    url="https://docs.myapi.com",
    params={
        "limit": 500,
        "scrapeOptions": {
            "formats": ["markdown"],
            "onlyMainContent": True
        },
        "allowedDomains": ["docs.myapi.com"]
    }
)

# Save to files
for page in docs.get("data", []):
    filename = page["url"].replace("https://", "").replace("/", "_") + ".md"
    with open(f"docs/{filename}", "w") as f:
        f.write(page["markdown"])
2. 提取产品数据

场景:为电子商务提取结构化产品数据

const schema = z.object({
  title: z.string(),
  price: z.number(),
  description: z.string(),
  images: z.array(z.string()),
  in_stock: z.boolean()
});

const products = await app.extract({
  urls: productUrls,
  schema: schema,
  systemPrompt: 'Extract all product details including price and availability'
});
3. 抓取新闻文章

场景:提取干净的文章内容,不含广告和导航栏

article = app.scrape_url(
    url="https://news.com/article",
    params={
        "formats": ["markdown"],
        "onlyMainContent": True,
        "removeBase64Images": True
    }
)

# Get clean markdown
content = article.get("markdown")

错误处理

Python
from firecrawl import FirecrawlApp
from firecrawl.exceptions import FirecrawlException

app = FirecrawlApp(api_key=os.environ.get("FIRECRAWL_API_KEY"))

try:
    result = app.scrape_url("https://example.com")
except FirecrawlException as e:
    print(f"Firecrawl error: {e}")
except Exception as e:
    print(f"Unexpected error: {e}")
TypeScript
import FirecrawlApp from '@mendable/firecrawl-js';

const app = new FirecrawlApp({
  apiKey: process.env.FIRECRAWL_API_KEY
});

try {
  const result = await app.scrapeUrl('https://example.com');
} catch (error) {
  if (error.response) {
    // API error
    console.error('API Error:', error.response.data);
  } else {
    // Network or other error
    console.error('Error:', error.message);
  }
}

速率限制与最佳实践

速率限制
  • 免费套餐:每月 500 个额度
  • 付费套餐:额度上限根据套餐而定
  • 不同端点和选项消耗的额度有所不同
最佳实践
  1. 使用 onlyMainContent: true,以减少额度消耗并获取更干净的数据
  2. 为抓取设置合理的上限,避免产生过高费用
  3. 使用指数退避处理重试,应对暂时性错误
  4. 在本地缓存结果,避免重复抓取相同内容
  5. 先使用 map 端点制定抓取策略
  6. 批量调用提取接口,以处理多个 URL
  7. 在控制面板中监控额度用量

Cloudflare Workers 集成

⚠️ 重要提示:SDK 兼容性

Firecrawl SDK 无法在 Cloudflare Workers 中运行,因为它依赖 Node.js(特别是使用 Node.js http 模块的 axios)。Workers 需要使用 Web 标准 API。

✅ 请改用 fetch 直接调用 REST API(参见下方示例)。

替代方案:使用 workers-firecrawl 自托管——这是一个适用于 Workers 的原生实现(需要 Workers Paid Plan,且仅实现了 /search 端点)。


Workers 示例:直接调用 REST API

此示例使用 fetch API 直接调用 Firecrawl,可在 Cloudflare Workers 中完美运行:

interface Env {
  FIRECRAWL_API_KEY: string;
  SCRAPED_CACHE?: KVNamespace; // Optional: for caching results
}

interface FirecrawlScrapeResponse {
  success: boolean;
  data: {
    markdown?: string;
    html?: string;
    metadata: {
      title?: string;
      description?: string;
      language?: string;
      sourceURL: string;
    };
  };
}

export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    if (request.method !== 'POST') {
      return Response.json({ error: 'Method not allowed' }, { status: 405 });
    }

    try {
      const { url } = await request.json<{ url: string }>();

      if (!url) {
        return Response.json({ error: 'URL is required' }, { status: 400 });
      }

      // Check cache (optional)
      if (env.SCRAPED_CACHE) {
        const cached = await env.SCRAPED_CACHE.get(url, 'json');
        if (cached) {
          return Response.json({ cached: true, data: cached });
        }
      }

      // Call Firecrawl API directly using fetch
      const response = await fetch('https://api.firecrawl.dev/v2/scrape', {
        method: 'POST',
        headers: {
          'Authorization': `Bearer ${env.FIRECRAWL_API_KEY}`,
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          url: url,
          formats: ['markdown'],
          onlyMainContent: true,
          removeBase64Images: true
        })
      });

      if (!response.ok) {
        const errorText = await response.text();
        throw new Error(`Firecrawl API error (${response.status}): ${errorText}`);
      }

      const result = await response.json<FirecrawlScrapeResponse>();

      // Cache for 1 hour (optional)
      if (env.SCRAPED_CACHE && result.success) {
        await env.SCRAPED_CACHE.put(
          url,
          JSON.stringify(result.data),
          { expirationTtl: 3600 }
        );
      }

      return Response.json({
        cached: false,
        data: result.data
      });

    } catch (error) {
      console.error('Scraping error:', error);
      return Response.json(
        { error: error instanceof Error ? error.message : 'Unknown error' },
        { status: 500 }
      );
    }
  }
};

环境设置:在 Wrangler secrets 中添加 FIRECRAWL_API_KEY:

npx wrangler secret put FIRECRAWL_API_KEY

可选的 KV 绑定(用于缓存——添加到 wrangler.jsonc 中):

{
  "kv_namespaces": [
    {
      "binding": "SCRAPED_CACHE",
      "id": "your-kv-namespace-id"
    }
  ]
}

参见 templates/firecrawl-worker-fetch.ts,了解完整的生产就绪示例。


何时使用此技能

✅ 以下情况适合使用 Firecrawl:

  • 抓取使用 JavaScript 的现代网站
  • 需要适用于大模型的纯净 Markdown 输出
  • 基于网页内容构建 RAG 系统
  • 大规模提取结构化数据
  • 应对机器人防护
  • 需要可靠、可用于生产环境的抓取方案

❌ 以下情况不适合使用 Firecrawl:

  • 抓取简单的静态 HTML(使用 cheerio/beautifulsoup)
  • 已有运行良好的 Puppeteer/Playwright 配置
  • 使用 API(请改为直接调用 API)
  • 预算有限(免费套餐有使用限制)

常见问题与解决方案

问题:“Invalid API Key”

原因:未设置 API 密钥或密钥不正确 解决方法:

# Check env variable is set
echo $FIRECRAWL_API_KEY

# Verify key format (should start with fc-)
问题:“Rate limit exceeded”

原因:超出每月额度 解决方法:

  • 在控制面板中查看用量
  • 升级套餐或等待额度重置
  • 使用 onlyMainContent: true 以减少额度消耗
问题:“Timeout error”

原因:页面加载时间过长 解决方法:

result = app.scrape_url(url, params={"waitFor": 10000})  # Wait 10s
问题:“Content is empty”

原因:内容在初始渲染后通过 JavaScript 加载 解决方法:

result = app.scrape_url(url, params={
    "waitFor": 5000,
    "actions": [{"type": "wait", "milliseconds": 3000}]
})

高级功能

浏览器操作

在抓取前执行交互操作:

result = app.scrape_url(
    url="https://example.com",
    params={
        "actions": [
            {"type": "click", "selector": "button.load-more"},
            {"type": "wait", "milliseconds": 2000},
            {"type": "scroll", "direction": "down"}
        ]
    }
)
自定义请求头
result = app.scrape_url(
    url="https://example.com",
    params={
        "headers": {
            "User-Agent": "Custom Bot 1.0",
            "Accept-Language": "en-US"
        }
    }
)
长时间爬取的 Webhook

无需轮询,可通过 webhook 接收结果:

crawl = app.crawl_url(
    url="https://docs.example.com",
    params={
        "limit": 1000,
        "webhook": "https://your-domain.com/webhook"
    }
)

软件包版本

软件包版本上次检查时间
firecrawl-py4.5.0+2025-10-20
@mendable/firecrawl-js(或 firecrawl)4.4.1+2025-10-24
API 版本v2当前

注意:Node.js SDK 要求 Node.js >=22.0.0,且无法在 Cloudflare Workers 中运行。在 Workers 中请直接调用 REST API(参见 Cloudflare Workers 集成部分)。


官方文档


使用此技能后的后续步骤

  1. 存储抓取的数据:使用 Cloudflare D1、R2 或 KV 持久化结果
  2. 构建 RAG 系统:结合 Vectorize 实现语义搜索
  3. 添加定时任务:使用 Cloudflare Queues 定期抓取
  4. 处理内容:使用 Workers AI 分析抓取的数据

节省 Token:与手动集成相比约节省 60% 预防错误:API 身份验证、速率限制、格式处理 可用于生产环境:✅

评论

支持 Markdown