> ## Documentation Index
> Fetch the complete documentation index at: https://student-213fb9fc.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# 爬取

> Firecrawl 可递归遍历某个 URL 的子域，并收集其内容

Firecrawl 高效爬取网站，在处理复杂的 Web 基础架构的同时提取全面数据。流程如下：

1. **URL 分析：** 扫描 sitemap 并爬取网站以识别链接
2. **遍历：** 递归跟随链接以发现所有子页面
3. **抓取：** 从各页面提取内容，处理 JS 与速率限制
4. **输出：** 将数据转换为干净的 Markdown 或结构化格式

确保可从任意起始 URL 全面采集数据。

<Card title="在 Playground 中试用" icon="play" href="https://www.firecrawl.dev/playground?endpoint=crawl">
  在交互式 Playground 中测试爬取功能——无需代码。
</Card>

<div id="crawling">
  ## 爬虫
</div>

<div id="crawl-endpoint">
  ### /crawl 端点
</div>

用于抓取某个 URL 及其所有可访问的子页面。该操作会提交一个抓取任务，并返回任务 ID 以便查询抓取状态。

<Warning>
  默认情况下，如果页面中的子链接并非你提供的 URL 的下级路径，Crawl 会忽略它们。因此，若你抓取 website.com/blogs/，则不会返回 website.com/other-parent/blog-1。若需要包含 website.com/other-parent/blog-1，请使用 `crawlEntireDomain` 参数。若在抓取 website.com 时需要抓取其子域名（如 blog.website.com），请使用 `allowSubdomains` 参数。
</Warning>

<Info>
  默认情况下，crawler 会包含网站的 sitemap 来发现 URL（`sitemap: "include"`）。如果你将其设置为 `sitemap: "skip"`，crawler 只会从根 URL 开始，通过 HTML 链接可达的页面来发现内容。像 PDF 这类资源，或仅在 sitemap 中列出但未从任何 HTML 页面直接链接的深层页面将会被遗漏。为获得最大覆盖范围，请保持默认的 `sitemap: "include"` 设置。
</Info>

<div id="installation">
  ### 安装
</div>

<CodeGroup>
  ```python Python theme={null}
  # 使用 pip 安装 firecrawl-py

  from firecrawl import Firecrawl

  firecrawl = Firecrawl(api_key="fc-YOUR-API-KEY")
  ```

  ```js Node theme={null}
  # 使用 npm 安装 @mendable/firecrawl-js

  import Firecrawl from '@mendable/firecrawl-js';

  const firecrawl = new Firecrawl({ apiKey: "fc-YOUR-API-KEY" });
  ```

  ```bash CLI theme={null}
  # 使用 npm 全局安装
  npm install -g firecrawl

  # 身份验证(一次性设置)
  firecrawl login
  ```
</CodeGroup>

<div id="usage">
  ### 用法
</div>

<CodeGroup>
  ```python Python theme={null}
  from firecrawl import Firecrawl

  firecrawl = Firecrawl(api_key="fc-你的API密钥")

  docs = firecrawl.crawl(url="https://docs.firecrawl.dev", limit=10)
  print(docs)
  ```

  ```js Node theme={null}
  import Firecrawl from '@mendable/firecrawl-js';

  const firecrawl = new Firecrawl({ apiKey: "fc-你的API密钥" });

  const docs = await firecrawl.crawl('https://docs.firecrawl.dev', { limit: 10 });
  console.log(docs);
  ```

  ```bash cURL theme={null}
  curl -s -X POST "https://api.firecrawl.dev/v2/crawl" \
    -H "Authorization: Bearer $FIRECRAWL_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "url": "https://docs.firecrawl.dev",
      "limit": 10
    }'
  ```

  ```bash CLI theme={null}
  # 启动爬取任务(返回任务 ID)
  firecrawl crawl https://firecrawl.dev

  # 等待完成并显示进度
  firecrawl crawl https://firecrawl.dev --wait --progress --limit 100
  ```
</CodeGroup>

<Info>
  每抓取 1 个页面会消耗 1 个积分。抓取的默认 `limit` 为 10,000 个页面，你可以设置更低的 `limit` 来控制积分消耗（例如将 `limit` 设为 100）。某些选项会额外消耗积分：JSON 模式每个页面额外消耗 4 个积分，增强代理每个页面额外消耗 4 个积分，PDF 解析每个 PDF 页面额外消耗 1 个积分。
</Info>

<div id="scrape-options-in-crawl">
  ### 在 Crawl 中使用 Scrape 选项
</div>

Scrape 端点的所有选项都可通过 `scrapeOptions`（JS）/ `scrape_options`（Python）在 Crawl 中使用。它们将应用于爬虫抓取的每个页面：formats、proxy、caching、actions、location、tags 等。完整列表参见 [Scrape API Reference](https://docs.firecrawl.dev/api-reference/endpoint/scrape)。

<CodeGroup>
  ```js Node theme={null}
  import Firecrawl from '@mendable/firecrawl-js';

  const firecrawl = new Firecrawl({ apiKey: 'fc-YOUR_API_KEY' });

  // 使用 scrape 选项进行爬取
  const crawlResponse = await firecrawl.crawl('https://example.com', {
    limit: 100,
    scrapeOptions: {
      formats: [
        'markdown',
        {
          type: 'json',
          schema: { type: 'object', properties: { title: { type: 'string' } } },
        },
      ],
      proxy: 'auto',
      maxAge: 600000,
      onlyMainContent: true,
    },
  });
  ```

  ```python Python theme={null}
  from firecrawl import Firecrawl

  firecrawl = Firecrawl(api_key='fc-YOUR_API_KEY')

  # 使用 scrape 选项进行爬取
  response = firecrawl.crawl('https://example.com',
      limit=100,
      scrape_options={
          'formats': [
              'markdown',
              { 'type': 'json', 'schema': { 'type': 'object', 'properties': { 'title': { 'type': 'string' } } } }
          ],
          'proxy': 'auto',
          'max_age': 600000,
          'only_main_content': True
      }
  )
  ```
</CodeGroup>

<div id="api-response">
  ### API 响应
</div>

如果你使用 cURL 或 starter 方法，将返回一个用于检查爬取状态的 `ID`。

<Note>
  如果你使用 SDK，请参见下方方法，了解 waiter 与 starter 的行为差异。
</Note>

```json theme={null}
{
  "success": true,
  "id": "123-456-789",
  "url": "https://api.firecrawl.dev/v2/crawl/123-456-789"
}
```

<div id="check-crawl-job">
  ### 检查爬取任务
</div>

用于检查爬取任务的状态并获取结果。

<Note>
  任务结果在完成后 24 小时内可通过 API 获取。此后，你仍可以在[活动日志](https://www.firecrawl.dev/app/logs)中查看你的爬取历史和结果。
</Note>

<Note>
  爬取结果中的 `data` 数组里包含的是 Firecrawl 成功抓取的页面 —— 即使目标站点返回了 404 等 HTTP 错误。`metadata.statusCode` 字段显示的是目标站点返回的 HTTP 状态码。若要获取 Firecrawl 本身未能成功抓取的页面（例如网络错误、超时或被 robots.txt 拦截），请使用专门的 [Get Crawl Errors](/zh/api-reference/endpoint/crawl-get-errors) 端点（`GET /crawl/{id}/errors`）。
</Note>

<CodeGroup>
  ```python Python theme={null}
  status = firecrawl.get_crawl_status("<crawl-id>")
  print(status)
  ```

  ```js Node theme={null}
  const status = await firecrawl.getCrawlStatus("<crawl-id>");
  console.log(status);
  ```

  ```bash cURL theme={null}
  # 启动爬取后，使用 jobId 轮询状态
  curl -s -X GET "https://api.firecrawl.dev/v2/crawl/<jobId>" \
    -H "Authorization: Bearer $FIRECRAWL_API_KEY"
  ```

  ```bash CLI theme={null}
  # 使用作业 ID 检查爬取状态
  firecrawl crawl <job-id>
  ```
</CodeGroup>

<div id="response-handling">
  #### 响应处理
</div>

响应会根据爬取任务的状态而有所不同。

对于未完成的任务或超过 10MB 的大型响应，会返回一个 `next` URL 参数。你需要请求该 URL 以获取后续的每 10MB 数据。如果没有 `next` 参数，则表示爬取数据已结束。

`skip` 参数用于设置每个结果分块所返回的最大条目数。

<Info>
  仅在直接调用 API 时，skip 和 next 参数才生效。
  如果你使用 SDK，我们会代为处理，并一次性返回全部结果。
</Info>

<CodeGroup>
  ```json 抓取中 theme={null}
  {
    "status": "抓取中",
    "total": 36,
    "completed": 10,
    "creditsUsed": 10,
    "expiresAt": "2024-00-00T00:00:00.000Z",
    "next": "https://api.firecrawl.dev/v2/crawl/123-456-789?skip=10",
    "data": [
      {
        "markdown": "[Firecrawl 文档首页![浅色标志](https://mintlify.s3-us-west-1.amazonaws.com/firecrawl/logo/light.svg)!...",
        "html": "<!DOCTYPE html><html lang=\"en\" class=\"js-focus-visible lg:[--scroll-mt:9.5rem]\" data-js-focus-visible=\"\">...",
        "metadata": {
          "title": "使用 Groq Llama 3 构建“网站聊天” | Firecrawl",
          "language": "en",
          "sourceURL": "https://docs.firecrawl.dev/learn/rag-llama3",
          "description": "了解如何使用 Firecrawl、Groq Llama 3 和 Langchain 构建一个“网站聊天”机器人。",
          "ogLocaleAlternate": [],
          "statusCode": 200
        }
      },
      ...
    ]
  }
  ```

  ```json 已完成 theme={null}
  {
    "status": "completed",
    "total": 36,
    "completed": 36,
    "creditsUsed": 36,
    "expiresAt": "2024-00-00T00:00:00.000Z",
    "next": "https://api.firecrawl.dev/v2/crawl/123-456-789?skip=26",
    "data": [
      {
        "markdown": "[Firecrawl 文档首页![浅色 logo](https://mintlify.s3-us-west-1.amazonaws.com/firecrawl/logo/light.svg)!...",
        "html": "<!DOCTYPE html><html lang=\"en\" class=\"js-focus-visible lg:[--scroll-mt:9.5rem]\" data-js-focus-visible=\"\">...",
        "metadata": {
          "title": "使用 Groq Llama 3 构建“网站聊天” | Firecrawl",
          "language": "en",
          "sourceURL": "https://docs.firecrawl.dev/learn/rag-llama3",
          "description": "了解如何使用 Firecrawl、Groq Llama 3 和 LangChain 构建一个“网站聊天”机器人。",
          "ogLocaleAlternate": [],
          "statusCode": 200
        }
      },
      ...
    ]
  }
  ```
</CodeGroup>

<div id="sdk-methods">
  ### SDK 方法
</div>

使用 SDK 有两种方式：

1. **抓取并等待**（`crawl`）：
   * 等待爬取完成并返回完整响应
   * 自动处理分页
   * 适用于大多数场景，推荐使用

<CodeGroup>
  ```python Python theme={null}
  from firecrawl import Firecrawl
  from firecrawl.types import ScrapeOptions

  firecrawl = Firecrawl(api_key="fc-YOUR_API_KEY")

  # 爬取网站：
  crawl_status = firecrawl.crawl(
    'https://firecrawl.dev', 
    limit=100, 
    scrape_options=ScrapeOptions(formats=['markdown', 'html']),
    poll_interval=30
  )
  print(crawl_status)
  ```

  ```js Node theme={null}
  import Firecrawl from '@mendable/firecrawl-js';

  const firecrawl = new Firecrawl({ apiKey: "fc-你的_API_KEY" });

  const crawlResponse = await firecrawl.crawl('https://firecrawl.dev', {
    limit: 100,
    scrapeOptions: {
      formats: ['markdown', 'html'],
    }
  })

  console.log(crawlResponse)
  ```
</CodeGroup>

响应包括爬取状态及所有抓取到的数据：

<CodeGroup>
  ```bash Python theme={null}
  success=True
  status='completed'
  completed=100
  total=100
  creditsUsed=100
  expiresAt=datetime.datetime(2025, 4, 23, 19, 21, 17, tzinfo=TzInfo(UTC))
  next=None
  data=[
    Document(
      markdown='[第 7 天 - 发布周 III · 集成日（4 月 14 日至 20 日）](...',
      metadata={
        'title': '15 个 Python 网页爬取项目：从入门到进阶',
        ...
        'scrapeId': '97dcf796-c09b-43c9-b4f7-868a7a5af722',
        'sourceURL': 'https://www.firecrawl.dev/blog/python-web-scraping-projects',
        'url': 'https://www.firecrawl.dev/blog/python-web-scraping-projects',
        'statusCode': 200
      }
    ),
    ...
  ]
  ```

  ```json Node theme={null}
  {
    success: true,
    status: "completed",
    completed: 100,
    total: 100,
    creditsUsed: 100,
    expiresAt: "2025-04-23T19:28:45.000Z",
    data: [
      {
        markdown: "[第 7 天 - 发布周 III · 集成日（4 月）..."
        html: `<!DOCTYPE html><html lang="en" class="light" style="color...`,
        metadata: [Object],
      },
      ...
    ]
  }
  ```
</CodeGroup>

2. **启动后轮询状态**（`startCrawl`/`start_crawl`）：
   * 立即返回一个爬取 ID
   * 支持手动检查进度/状态
   * 适合长时间运行的爬取或自定义轮询逻辑

<CodeGroup>
  ```python Python theme={null}
  from firecrawl import Firecrawl

  firecrawl = Firecrawl(api_key="fc-YOUR-API-KEY")

  job = firecrawl.start_crawl(url="https://docs.firecrawl.dev", limit=10)
  print(job)

  # 检查爬取任务的状态
  status = firecrawl.get_crawl_status(job.id)
  print(status)
  ```

  ```js Node（Node.js） theme={null}
  import Firecrawl from '@mendable/firecrawl-js';

  const firecrawl = new Firecrawl({ apiKey: "fc-YOUR-API-KEY" });

  const { id } = await firecrawl.startCrawl('https://docs.firecrawl.dev', { limit: 10 });
  console.log(id);

  // 检查抓取进度
  const status = await firecrawl.getCrawlStatus(id);
  console.log(status);

  ```

  ```bash cURL theme={null}
  curl -s -X POST "https://api.firecrawl.dev/v2/crawl" \
    -H "Authorization: Bearer $FIRECRAWL_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "url": "https://docs.firecrawl.dev",
      "limit": 10
    }'
  ```

  ```bash CLI theme={null}
  # 启动爬取(异步,立即返回作业 ID)
  firecrawl crawl https://firecrawl.dev --limit 100

  # 稍后检查状态
  firecrawl crawl <job-id>
  ```
</CodeGroup>

<div id="crawl-websocket">
  ## 爬取 WebSocket
</div>

Firecrawl 基于 WebSocket 的方法 `Crawl URL and Watch` 支持实时数据提取与监控。以 URL 启动爬取，并可通过页面数量上限、允许的域名、输出 formats 等选项进行自定义，适用于即时数据处理需求。

<CodeGroup>
  ```python Python theme={null}
  import asyncio
  from firecrawl import AsyncFirecrawl

  async def main():
      firecrawl = AsyncFirecrawl(api_key="fc-YOUR-API-KEY")

      # 首先启动爬取
      started = await firecrawl.start_crawl("https://firecrawl.dev", limit=5)

      # 监听更新（快照）直到终止状态
      async for snapshot in firecrawl.watcher(started.id, kind="crawl", poll_interval=2, timeout=120):
          if snapshot.status == "completed":
              print("完成", snapshot.status)
              for doc in snapshot.data:
                  print("文档", doc.metadata.source_url if doc.metadata else None)
          elif snapshot.status == "failed":
              print("错误", snapshot.status)
          else:
              print("状态", snapshot.status, snapshot.completed, "/", snapshot.total)

  asyncio.run(main())
  ```

  ```js Node theme={null}
  import Firecrawl from '@mendable/firecrawl-js';

  const firecrawl = new Firecrawl({ apiKey: 'fc-YOUR-API-KEY' });

  // 启动一次爬取并开始监控
  const { id } = await firecrawl.startCrawl('https://mendable.ai', {
    excludePaths: ['blog/*'],
    limit: 5,
  });

  const watcher = firecrawl.watcher(id, { kind: 'crawl', pollInterval: 2, timeout: 120 });

  watcher.on('document', (doc) => {
    console.log('DOC', doc);
  });

  watcher.on('error', (err) => {
    console.error('ERR', err?.error || err);
  });

  watcher.on('done', (state) => {
    console.log('DONE', state.status);
  });

  // 开始监控（优先使用 WS，回退到 HTTP）
  await watcher.start();
  ```
</CodeGroup>

<div id="crawl-webhook">
  ## 爬取 Webhook
</div>

你可以配置 webhook，在爬取过程中实时接收通知，从而在页面被抓取后立即进行处理，而无需等待整个爬取任务完成。

```bash cURL theme={null}
curl -X POST https://api.firecrawl.dev/v2/crawl \
    -H 'Content-Type: application/json' \
    -H 'Authorization: Bearer YOUR_API_KEY' \
    -d '{
      "url": "https://docs.firecrawl.dev",
      "limit": 100,
      "webhook": {
        "url": "https://your-domain.com/webhook",
        "metadata": {
          "any_key": "any_value"
        },
        "events": ["started", "page", "completed"]
      }
    }'
```

<div id="quick-reference">
  ### 快速参考
</div>

**事件类型：**

* `crawl.started` - 爬取开始时触发
* `crawl.page` - 每成功抓取一个页面时触发
* `crawl.completed` - 爬取完成时触发
* `crawl.failed` - 爬取出错时触发

**基本负载：**

```json theme={null}
{
  "success": true,
  "type": "crawl.page",
  "id": "crawl-job-id",
  "data": [...], // 'page' 事件的页面数据
  "metadata": {}, // Your custom metadata
  "error": null
}
```

<div id="security-verifying-webhook-signatures">
  ### 安全：验证 Webhook 签名
</div>

来自 Firecrawl 的每个 webhook 请求都会包含一个 `X-Firecrawl-Signature` 请求头，其中含有一个 HMAC-SHA256 签名。**务必验证此签名**，以确保 webhook 为真实请求且未被篡改。

**工作原理：**

1. 在账户设置中的 [Advanced（高级）选项卡](https://www.firecrawl.dev/app/settings?tab=advanced) 获取你的 webhook 密钥（secret）
2. 从 `X-Firecrawl-Signature` 请求头中提取签名
3. 使用该密钥对原始请求体计算 HMAC-SHA256
4. 使用时间安全函数（timing-safe function）将计算结果与签名请求头中的值进行比较

<Warning>
  在验证签名之前，切勿处理任何 webhook。`X-Firecrawl-Signature` 请求头中的签名格式为：`sha256=abc123def456...`
</Warning>

有关 JavaScript 和 Python 的完整实现示例，请参阅 [Webhook 安全文档](/zh/webhooks/security)。

<div id="full-documentation">
  ### 完整文档
</div>

有关完整的 webhook 文档（包括事件负载详情、负载结构、高级配置和故障排除指南），请参阅[Webhook 文档](/zh/webhooks/overview)。
