> ## Documentation Index
> Fetch the complete documentation index at: https://firecrawl.web3doc.top/llms.txt
> Use this file to discover all available pages before exploring further.

# 爬取

> Firecrawl 可以递归地搜索 URL 的子域名，并收集内容。

Firecrawl 彻底爬取网站，确保全面的数据提取，同时绕过任何网络阻止机制。其工作原理如下：

1. **URL 分析**:
   从一个指定的 URL 开始，通过查看站点地图来识别链接，然后爬取网站。如果没有找到站点地图，它将按照链接爬取网站。

2. **递归遍历**:
   递归地跟随每个链接以发现所有子页面。

3. **内容抓取**:
   从每个访问过的页面中收集内容，同时处理诸如 JavaScript 渲染或速率限制等复杂性。

4. **结果编译**:
   将收集到的数据转换为干净的 markdown 或结构化输出，非常适合 LLM 处理或其他任务。

此方法保证了从任何起始 URL 进行彻底的爬取和数据收集。

## 爬取

### /crawl 端点

用于爬取一个 URL 及其所有可访问的子页面。这提交了一个爬取作业，并返回一个作业 ID，用于检查爬取状态。

<Warning>默认情况下 - 如果子链接不是您提供的 URL 的子节点，爬取将忽略这些子链接。因此，如果您爬取 website.com/blogs/，则不会返回 website.com/other-parent/blog-1。如果您需要 website.com/other-parent/blog-1，请使用 `allowBackwardLinks` 参数。</Warning>

### 安装

<CodeGroup>
  ```bash Python theme={null}
  pip install firecrawl-py
  ```

  ```bash Node theme={null}
  npm install @mendable/firecrawl-js
  ```

  ```bash Go theme={null}
  go get github.com/mendableai/firecrawl-go
  ```

  ```yaml Rust theme={null}
  # 将以下内容添加到您的Cargo.toml中
  [dependencies]
  firecrawl = "^1.0"
  tokio = { version = "^1", features = ["full"] }
  ```
</CodeGroup>

### 用法

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

  app = FirecrawlApp(api_key="fc-YOUR_API_KEY")

  # 爬取一个网站:
  crawl_status = app.crawl_url(
    'https://firecrawl.dev',
    params={
      'limit': 100,
      'scrapeOptions': {'formats': ['markdown', 'html']}
    },
    poll_interval=30
  )
  print(crawl_status)
  ```

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

  const app = new FirecrawlApp({apiKey: "fc-YOUR_API_KEY"});

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

  if (!crawlResponse.success) {
    throw new Error(`Failed to crawl: ${crawlResponse.error}`)
  }

  console.log(crawlResponse)
  ```

  ```go Go theme={null}
  import (
  	"fmt"
  	"log"

  	"github.com/mendableai/firecrawl-go"
  )

  func main() {
  	// 使用您的 API 密钥初始化 FirecrawlApp
  	apiKey := "fc-YOUR_API_KEY"
  	apiUrl := "https://api.firecrawl.dev"
  	version := "v1"

  	app, err := firecrawl.NewFirecrawlApp(apiKey, apiUrl, version)
  	if err != nil {
  		log.Fatalf("无法初始化 FirecrawlApp: %v", err)
  	}

  	// 爬取一个网站
  	crawlStatus, err := app.CrawlUrl("https://firecrawl.dev", map[string]any{
  		"limit": 100,
  		"scrapeOptions": map[string]any{
  			"formats": []string{"markdown", "html"},
  		},
  	})
  	if err != nil {
  		log.Fatalf("发送爬取请求失败: %v", err)
  	}

  	fmt.Println(crawlStatus) 
  }
  ```

  ```rust Rust theme={null}
  use firecrawl::{crawl::{CrawlOptions, CrawlScrapeOptions, CrawlScrapeFormats}, FirecrawlApp};

  #[tokio::main]
  async fn main() {
      // 使用API密钥初始化FirecrawlApp
      let app = FirecrawlApp::new("fc-YOUR_API_KEY").expect("无法初始化FirecrawlApp");

      // 爬取网站
      let crawl_options = CrawlOptions {
          scrape_options: CrawlScrapeOptions {
              formats: vec![CrawlScrapeFormats::Markdown, CrawlScrapeFormats::HTML].into(),
              ..Default::default()
          }.into(),
          limit: 100.into(),
          ..Default::default()
      };

      let crawl_result = app
          .crawl_url("https://mendable.ai", crawl_options)
          .await;

      match crawl_result {
          Ok(data) => println!("爬取结果（使用了{}积分）：
  {:#?}", data.credits_used, data.data),
          Err(e) => eprintln!("爬取失败：{}", e),
      }
  }
  ```

  ```bash cURL theme={null}
  curl -X POST https://api.firecrawl.dev/v1/crawl \
      -H 'Content-Type: application/json' \
      -H 'Authorization: Bearer YOUR_API_KEY' \
      -d '{
        "url": "https://docs.firecrawl.dev",
        "limit": 100,
        "scrapeOptions": {
          "formats": ["markdown", "html"]
        }
      }'
  ```
</CodeGroup>

### 响应

如果您正在使用 cURL 或 SDK 上的 `async crawl` 函数，这将返回一个 `ID`，您可以使用它来检查爬取的状态。

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

### 检查爬取作业

用于检查爬取作业的状态并获取其结果。

<Note>此端点仅适用于正在进行中的爬取或最近完成的爬取。</Note>

<CodeGroup>
  ```python Python theme={null}
  crawl_status = app.check_crawl_status("<crawl_id>")
  print(crawl_status)
  ```

  ```js Node theme={null}
  Node;
  const crawlResponse = await app.checkCrawlStatus('<crawl_id>');

  if (!crawlResponse.success) {
    throw new Error(`Failed to check crawl status: ${crawlResponse.error}`);
  }

  console.log(crawlResponse);
  ```

  ```go Go theme={null}
  // 获取爬取状态
  crawlStatus, err := app.CheckCrawlStatus("<crawl_id>")

  if err != nil {
    log.Fatalf("获取爬取状态失败: %v", err)
  }

  fmt.Println(crawlStatus)
  ```

  ```rust Rust theme={null}
  let crawl_status = app.check_crawl_status(crawl_id).await;

  match crawl_status {
      Ok(data) => println!("Crawl Status:\n{:#?}", data),
      Err(e) => eprintln!("Check crawl status failed: {}", e),
  }
  ```

  ```bash cURL theme={null}
  curl -X GET https://api.firecrawl.dev/v1/crawl/<crawl_id> \
      -H 'Content-Type: application/json' \
      -H 'Authorization: Bearer YOUR_API_KEY'
  ```
</CodeGroup>

#### 响应处理

根据爬取的状态，响应会有所不同。

对于未完成或超过 10MB 的大型响应，会提供一个 `next` URL 参数。您必须请求此 URL 以检索下一组 10MB 的数据。如果缺少 `next` 参数，则表示爬取数据的结束。

skip 参数设置了每次返回的结果块的最大数量。

<Info>
  当直接调用 API 时，skip 和 next 参数才相关。如果您使用的是 SDK，我们会为您处理这些，并将一次性返回所有结果。
</Info>

<CodeGroup>
  ```json theme={null}
  {
    "status": "scraping",
    "total": 36,
    "completed": 10,
    "creditsUsed": 10,
    "expiresAt": "2024-00-00T00:00:00.000Z",
    "next": "https://api.firecrawl.dev/v1/crawl/123-456-789?skip=10",
    "data": [
      {
        "markdown": "[Firecrawl Docs home page![light 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
        }
      },
      ...
    ]
  }
  ```

  ```json theme={null}
  {
    "status": "已完成",
    "total": 36,
    "completed": 36,
    "creditsUsed": 36,
    "expiresAt": "2024-00-00T00:00:00.000Z",
    "next": "https://api.firecrawl.dev/v1/crawl/123-456-789?skip=26",
    "data": [
      {
        "markdown": "[Firecrawl Docs home page![light 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>

## 爬取 WebSocket

Firecrawl 基于 WebSocket 的方法“爬取 URL 并监控”实现了实时数据提取和监控。使用一个 URL 启动爬取，并通过选项（如页面限制、允许的域名和输出格式）进行自定义，非常适合于即时数据处理需求。

<CodeGroup>
  ```python Python theme={null}
  # 在一个异步函数中...
  nest_asyncio.apply()

  # 定义事件处理程序
  def on_document(detail):
      print("DOC", detail)

  def on_error(detail):
      print("ERR", detail['error'])

  def on_done(detail):
      print("DONE", detail['status'])

  # 启动爬取和监视过程的函数
  async def start_crawl_and_watch():
      # 初始化爬取任务并获取监视器
      watcher = app.crawl_url_and_watch('firecrawl.dev', { 'excludePaths': ['blog/*'], 'limit': 5 })

      # 添加事件监听器
      watcher.add_event_listener("document", on_document)
      watcher.add_event_listener("error", on_error)
      watcher.add_event_listener("done", on_done)

      # 启动监视器
      await watcher.connect()

  # 运行事件循环
  await start_crawl_and_watch()
  ```

  ```js Node theme={null}
  const watch = await app.crawlUrlAndWatch('mendable.ai', { excludePaths: ['blog/*'], limit: 5});

  watch.addEventListener("document", doc => {
    console.log("DOC", doc.detail);
  });

  watch.addEventListener("error", err => {
    console.error("ERR", err.detail.error);
  });

  watch.addEventListener("done", state => {
    console.log("DONE", state.detail.status);
  });
  ```
</CodeGroup>

## 爬取 Webhook

现在可以将 `webhook` 参数传递给 `/crawl` 端点。这将在爬取开始、更新和完成时向指定的 URL 发送 POST 请求。

Webhook 现在将对每个爬取的页面触发，而不仅仅是在最后整个结果结束时触发。

```bash cURL theme={null}
curl -X POST https://api.firecrawl.dev/v1/crawl \
    -H 'Content-Type: application/json' \
    -H 'Authorization: Bearer YOUR_API_KEY' \
    -d '{
      "url": "https://docs.firecrawl.dev",
      "limit": 100,
      "webhook": "https://example.com/webhook"
    }'
```

### Webhook 事件

现在有四种类型的事件：

* `crawl.started` - 当爬取开始时触发。
* `crawl.page` - 对每个爬取的页面触发。
* `crawl.completed` - 当爬取完成时触发，让您知道它已完成（Beta）。\*\*
* `crawl.failed` - 当爬取失败时触发。

### Webhook 响应

* `success` - 如果 webhook 成功爬取页面。
* `type` - 发生的事件类型。
* `id` - 爬取的 ID。
* `data` - 被抓取的数据（数组）。这仅在 `crawl.page` 上非空，并且如果页面被成功抓取，将包含一个项目。响应与 `/scrape` 端点的响应相同。
* `error` - 如果 webhook 失败，这将包含错误消息。

**Beta 注意事项**

* 存在极小的可能性，即 `crawl.completed` 事件可能在最后的 `crawl.page` 事件仍在处理时被触发。我们正在修复这个问题。
