Web Scraping

用 Firecrawl 一個 API 呼叫搞定網頁抓取:格式、結構化資料與成本控制

Firecrawl /scrape 端點把任何 URL 轉成 Markdown、JSON、截圖、音訊等多種格式,伺服器端處理瀏覽器渲染與代理。本文拆解十一種格式、prompt vs schema 提取、正確的計價表(含快取仍計 1 credit 的細節)、Lockdown Mode 與批次/actions 互動。

用 Firecrawl 一個 API 呼叫搞定網頁抓取:格式、結構化資料與成本控制 — 文章封面
本頁內容6 個段落
  1. 一個端點,十一種輸出格式
  2. 結構化提取:提示詞 vs. 資料模型
  3. 定價與快取:一分錢一分延遲
  4. 批次操作與互動頁面
  5. 實際建議
  6. 參考來源

網頁抓取從來沒有變得更容易。JavaScript 渲染、反爬機制、地區差異的 HTML 結構,讓開發者往往得先寫一套下載器,再接一套清理管線,才能拿到乾淨的文字或結構化記錄。

Firecrawl 的 /scrape 端點試圖把這些步驟壓縮成一個 API 呼叫。你給一個 URL,指定想要的格式,它就在伺服器端用真實瀏覽器渲染頁面、處理代理與快取,然後回傳你要求的結果。這篇文章從產品建構者的角度,拆解這個端點的核心參數、定價邏輯,以及何時該用提示詞驅動的 JSON 提取、何時該用嚴格的資料模型。

一個端點,十一種輸出格式

/scrape 最直接的好處是「一次呼叫,多種回傳」。你可以同時要求 markdownhtmlrawHtmllinksscreenshotsummaryimagesjsonbrandingaudioquestion 格式,Firecrawl 會在同一個回應裡附上所有你指定的資料。

以下用 Python 向 arXiv.org 一次要求多種格式:

from firecrawl import Firecrawl
from dotenv import load_dotenv

load_dotenv()

app = Firecrawl()
url = "https://arxiv.org"

data = app.scrape(
    url,
    formats=['html', 'rawHtml', 'links', 'screenshot', 'summary', 'images']
)

markdown 為例,它會把頁面主內容轉成 LLM 友善的純文字,適合餵給 RAG 管線或摘要模型。screenshot 回傳一個簽名的 PNG URL,支援 fullPage 參數來擷取整頁。audio 則能直接從 YouTube 連結抽出 MP3,目前僅限 REST API 呼叫。

根據 Firecrawl 官方文件,這些格式的底層是同一套渲染引擎:頁面在無頭瀏覽器中載入,執行 JavaScript,處理重新導向,然後才根據 formats 參數產出對應的結果。這意味著你不需要自己維護瀏覽器實例或代理池。

結構化提取:提示詞 vs. 資料模型

當你需要從網頁中取出特定欄位(例如商品名稱、價格、庫存狀態),json 格式提供了兩種做法。

第一種是純提示詞驅動:你寫一段自然語言描述,例如「從這頁取出所有文章的標題、作者與分數」,Firecrawl 會讓 LLM 推論出欄位名稱與結構。這種方式速度快,但欄位名稱每次可能不同,下游程式需要彈性處理。

以 Hacker News 為例,用一段提示詞請它取出前三名故事:

url = "https://news.ycombinator.com"
data = app.scrape(
    url,
    formats=[
        "markdown",
        {
            "type": "json",
            "prompt": "Extract the top 3 stories on the page. For each story, include its title, the URL it links to, the points score, and the author who submitted it."
        }
    ]
)
print(data.json)

回傳的 JSON 大概會長這樣:

{
  "stories": [
    {
      "title": "BYOMesh – New LoRa mesh radio offers 100x the bandwidth",
      "url": "https://example.com/story1",
      "points": 209,
      "author": "nullagent"
    }
  ]
}

第二種是傳入 Pydantic schema(或對應的 JSON Schema),鎖死欄位名稱與型別。例如你定義 title: strpoints: int,回傳的 JSON 就會嚴格遵循這個結構,適合直接餵進資料庫或型別檢查嚴格的程式。

官方部落格示範了巢狀 schema 的寫法:

from pydantic import BaseModel, Field

class IndividualArticle(BaseModel):
    title: str = Field(description="The title of the news article")
    subtitle: str = Field(description="The subtitle")
    url: str = Field(description="The URL")
    author: str = Field(description="The author")
    date: str = Field(description="The publication date")
    read_duration: int = Field(description="Estimated reading time in minutes")
    topics: list[str] = Field(description="List of topics")

class NewsArticlesSchema(BaseModel):
    news_articles: list[IndividualArticle] = Field(description="Extracted articles")

data = app.scrape(
    url,
    formats=[
        {
            "type": "json",
            "schema": NewsArticlesSchema,
            "prompt": "Extract the top 5 stories as news articles."
        }
    ]
)
print(data.json)

Firecrawl 的教學文章以 Hacker News 為例,示範了兩種做法。如果你的團隊對輸出格式有強烈要求,建議使用 schema 模式;如果只是快速探索資料,提示詞模式就夠用了。

定價與快取:一分錢一分延遲

每次 /scrape 呼叫的基本成本是 1 個 credit。依官方計價表,會增加成本的選項:

  • JSON 提取:+4 credits(總共 5)
  • PDF 解析parsers=["pdf"]):每 PDF 頁 +1 credit
  • 音訊提取formats=["audio"],僅限 REST):+4 credits
  • ZDRzeroDataRetention=True,Enterprise):每頁 +1 credit

官方文件中的計價表整理如下:

功能 Credit 成本
基本抓取(任一單一格式) 1
JSON 提取(formats: [{type: "json"}] +4(總計 5)
增強代理(proxy: "enhanced" 同樣 1 credit,不加價
PDF 解析(parsers: ["pdf"] 每 PDF 頁 +1
音訊提取(formats: ["audio"],僅限 REST) +4(總計 5)
快取結果 1(快取省時間,不省 credits)

兩個實務上容易誤解的點:快取命中仍然收取完整 1 credit——快取省的是延遲不是帳單;增強代理與基本抓取同價(都是 1 credit/頁),不需要為了成本而避開它。你可以透過 max_age 參數控制快取窗口(毫秒;預設約兩天):0 強制重新抓取、3600000 一小時、86400000 一天;回應的 result.metadata.cache_state 會回報 "hit""miss"

對於安全敏感的場景,Firecrawl 提供 Lockdown Mode:設定 lockdown=True 後,端點只會從既有索引提供資料,不會發起新的對外請求。如果 URL 不在快取中,直接回傳錯誤。這在需要嚴格控制出站流量、並要求從索引快照做確定性重放的環境中很有用。

批次操作與互動頁面

當你需要處理數百或數千個 URL 時,單次呼叫就不夠了。Firecrawl 提供 batch_scrape()(同步)與 start_batch_scrape()(非同步)方法,讓你可以一次提交大量任務,並透過輪詢或回呼取得結果。

另一個實用功能是 actions 參數。你可以定義一系列動作,例如 clicktypewaitscreenshot,讓 Firecrawl 在頁面上執行互動後再抓取內容。官方教學示範了如何登入一個測試網站,然後擷取登入後的截圖。這對於需要表單填寫或按鈕點擊的場景非常關鍵。

實際建議

如果你是第一次嘗試,直接從 REST API 用 cURL 測試最簡單。確認格式與成本後,再改用 Python 或 Node SDK 整合進應用。如果你的團隊使用 Claude Desktop 或 Cursor,Firecrawl 也提供 MCP 伺服器,讓模型直接呼叫 firecrawl_scrape,不需要寫任何程式碼。

最基本的 cURL 請求如下,先用它確認回傳格式,再進一步整合:

curl -X POST https://api.firecrawl.dev/v2/scrape \
  -H "Authorization: Bearer $FIRECRAWL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com", "formats": ["markdown"]}'

最後提醒:快取不省 credits,但能大幅降低延遲。對於更新頻率低的頁面,設定一個合理的 max_age(例如 86400000,即一天)可以讓多個請求共享同一份快取,減少不必要的重複抓取。

Firecrawl 不是萬能工具——遇到需要登入後多步驟操作的複雜流程,仍然需要搭配 actions 或自行處理 session。但對於絕大多數「給我這個 URL 的乾淨資料」的需求,/scrape 端點已經把門檻降得很低了。

參考來源

本文由 AI 協助自上述來源整理,經人工審核後發布。

這篇內容對你有幫助嗎?

支持本站繼續整理實用的 AI 文章、教學與開發筆記。

請我喝杯咖啡
分享X電郵