Firecrawl - LLM向けWebスクレイピングAPIでクリーンなMarkdownを取得

中級 | 10分 で読める | 2026.04.24

公式ドキュメント

この記事の要点

• WebページをLLM最適化されたMarkdownに自動変換
• 広告・ナビゲーション・不要要素を自動除去しクリーンなテキストを抽出
• サイトマップクロール・並列実行・レート制限管理を標準装備

LLMアプリケーション(RAG・エージェント等)では、Web上の情報をクリーンなテキストとして取得する必要があります。Firecrawlは、WebページをLLM向けに最適化されたMarkdownに変換するスクレイピングAPIとして、開発者がコンテンツ抽出に費やす時間を大幅に削減します。本記事では、Firecrawlの特徴と実践的な利用方法を解説します。

Firecrawlとは

Firecrawlは、WebページをスクレイピングしてLLM最適化されたMarkdownに変換するAPIです。従来のスクレイピングツールと異なり、広告・ナビゲーション・不要なタグを自動で除去し、本文コンテンツのみを抽出します。

主要な特徴

  • LLM最適化Markdown: 見出し・リスト・コードブロック等を構造化して出力
  • 自動クリーニング: 広告・ナビゲーション・フッター等の不要要素を除去
  • サイトマップクロール: サイト全体を自動クロールし、複数ページを一括取得
  • レート制限管理: クロール速度を自動調整し、サーバーに負荷をかけない
  • 並列実行: 複数URLを同時処理
  • 構造化出力: JSONスキーマを指定して特定情報を抽出
  • Webフック: クロール完了時に通知

ポイント: FirecrawlはBeautifulSoupやPuppeteerのような低レベルツールではなく、「LLMアプリに最適なテキストを取得する」という高レベルな目的に特化したAPIです。

なぜFirecrawlが必要か

従来のスクレイピングには、以下の課題がありました。

従来の課題

  1. HTMLのノイズ: 広告・ナビゲーション・スクリプトタグ等が混在し、本文抽出が困難
  2. 構造化の難しさ: HTMLをMarkdownに変換するには複雑なパース処理が必要
  3. サイト全体のクロール: 手動でリンクを辿り、クロールキューを管理する必要がある
  4. レート制限: 過度なリクエストでサーバーに負荷をかけたり、IPブロックされるリスク

FirecrawlはこれらをすべてAPI一つで解決し、開発者はビジネスロジックに集中できます。

アーキテクチャ

flowchart TB
    subgraph Client["開発者環境"]
        A1["APIリクエスト"]
    end

    subgraph Firecrawl["Firecrawl API"]
        B1["URL Queue"]
        B2["Headless Browser<br/>(Puppeteer)"]
        B3["Content Extractor"]
        B4["Markdown Converter"]
        B5["Rate Limiter"]
    end

    subgraph Output["出力"]
        C1["Markdown"]
        C2["JSON (構造化)"]
    end

    A1 --> B1
    B1 --> B2
    B2 --> B3
    B3 --> B4
    B4 --> C1
    B4 --> C2
    B2 --> B5
    B5 --> B1
  • URL Queue: クロール対象URLをキューで管理
  • Headless Browser: PuppeteerでJavaScript実行後のHTMLを取得
  • Content Extractor: 本文コンテンツのみを抽出(広告・ナビゲーション除去)
  • Markdown Converter: HTMLをMarkdownに変換
  • Rate Limiter: リクエスト間隔を調整し、サーバーに負荷をかけない

インストール

APIキーの取得

# 公式サイトでアカウント登録
# https://www.firecrawl.dev/
# APIキーを取得

SDKのインストール

# Node.js
npm install @mendable/firecrawl-js

# Python
pip install firecrawl-py

実践メモ: Firecrawlは無料プランで月間一定回数まで利用可能です。有料プランでは無制限に使えます。

基本的な使い方

単一ページのスクレイピング

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

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

// URLをスクレイピング
const result = await app.scrapeUrl('https://example.com/article', {
  formats: ['markdown', 'html'],
});

console.log(result.markdown);
// 出力: クリーンなMarkdown(広告・ナビゲーション除去済み)

Pythonでの利用

from firecrawl import FirecrawlApp

app = FirecrawlApp(api_key='YOUR_API_KEY')

# URLをスクレイピング
result = app.scrape_url('https://example.com/article')

print(result['markdown'])
# 出力: クリーンなMarkdown

ポイント: Firecrawlは自動でJavaScriptを実行し、動的にレンダリングされたコンテンツも取得できます。SPAサイトでも動作します。

サイトマップクロール

サイト全体を自動クロールし、複数ページを一括取得できます。

サイトマップクロール例

// サイト全体をクロール
const crawlResult = await app.crawlUrl('https://example.com', {
  limit: 100, // 最大100ページ
  scrapeOptions: {
    formats: ['markdown'],
  },
});

console.log(`Crawled ${crawlResult.data.length} pages`);

crawlResult.data.forEach((page) => {
  console.log(`URL: ${page.metadata.url}`);
  console.log(`Title: ${page.metadata.title}`);
  console.log(`Markdown: ${page.markdown.substring(0, 200)}...`);
});

クロール範囲の制限

// 特定のパスのみクロール
const crawlResult = await app.crawlUrl('https://example.com', {
  limit: 50,
  allowedDomains: ['example.com'],
  includePaths: ['/blog/*'], // /blog/ 配下のみ
  excludePaths: ['/admin/*'], // /admin/ を除外
});

実践メモ: includePathsexcludePaths でクロール範囲を制限できます。これにより、不要なページ(ログイン画面・管理画面等)を除外し、コストを削減できます。

構造化出力

JSONスキーマを指定して、特定の情報を構造化して抽出できます。

スキーマ指定例

// ブログ記事の情報を構造化して抽出
const result = await app.scrapeUrl('https://example.com/blog/post-1', {
  formats: ['extract'],
  extract: {
    schema: {
      type: 'object',
      properties: {
        title: { type: 'string' },
        author: { type: 'string' },
        publishedDate: { type: 'string' },
        tags: {
          type: 'array',
          items: { type: 'string' },
        },
        content: { type: 'string' },
      },
      required: ['title', 'content'],
    },
  },
});

console.log(result.extract);
// 出力: { title: "...", author: "...", publishedDate: "...", tags: [...], content: "..." }

複数記事の一括抽出

// ブログ一覧ページから複数記事を抽出
const result = await app.scrapeUrl('https://example.com/blog', {
  formats: ['extract'],
  extract: {
    schema: {
      type: 'array',
      items: {
        type: 'object',
        properties: {
          title: { type: 'string' },
          url: { type: 'string' },
          excerpt: { type: 'string' },
        },
      },
    },
  },
});

console.log(result.extract);
// 出力: [{ title: "...", url: "...", excerpt: "..." }, ...]

ポイント: 構造化出力は、ページ構造が統一されているサイト(ブログ・ニュースサイト・ECサイト等)で特に有効です。

RAGアプリケーションとの統合

FirecrawlはRAG(Retrieval-Augmented Generation)アプリケーションで広く使われます。

Firecrawl + LangChain + Pinecone

import FirecrawlApp from '@mendable/firecrawl-js';
import { OpenAIEmbeddings } from '@langchain/openai';
import { PineconeStore } from '@langchain/pinecone';
import { Pinecone } from '@pinecone-database/pinecone';

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

// サイト全体をクロール
const crawlResult = await firecrawl.crawlUrl('https://docs.example.com', {
  limit: 200,
  scrapeOptions: {
    formats: ['markdown'],
  },
});

// Markdownをチャンクに分割
const documents = crawlResult.data.map((page) => ({
  pageContent: page.markdown,
  metadata: {
    url: page.metadata.url,
    title: page.metadata.title,
  },
}));

// ベクトル化してPineconeに保存
const pinecone = new Pinecone();
const pineconeIndex = pinecone.Index('docs');

const embeddings = new OpenAIEmbeddings();

await PineconeStore.fromDocuments(documents, embeddings, {
  pineconeIndex,
});

console.log('Documents indexed successfully');

詳細なRAG実装については、RAG 2025 - 最新の検索拡張生成技術を参照してください。

並列実行

複数URLを同時処理し、クロール時間を短縮できます。

並列スクレイピング例

const urls = [
  'https://example.com/page1',
  'https://example.com/page2',
  'https://example.com/page3',
  // ... 100個のURL
];

// すべてのURLを並列処理
const results = await Promise.all(
  urls.map((url) =>
    app.scrapeUrl(url, {
      formats: ['markdown'],
    })
  )
);

results.forEach((result, index) => {
  console.log(`URL: ${urls[index]}`);
  console.log(`Markdown: ${result.markdown.substring(0, 200)}...`);
});

注意: 並列実行数はプランによって制限されます。無料プランでは同時実行数に上限があるため、大規模クロールには有料プランを検討してください。

FirecrawlとBeautifulSoupの比較

従来のスクレイピングライブラリとの違いを理解しておくと、適切なツールを選択できます。

項目FirecrawlBeautifulSoup
実装方法API呼び出しPythonライブラリ
JavaScript実行自動対応別途Seleniumが必要
広告除去自動手動でセレクタ指定
Markdown変換自動手動で実装
レート制限自動管理手動で実装
コスト従量課金無料(サーバーコストは別)

API呼び出しで簡単にクリーンなMarkdownを取得したいならFirecrawl、細かい制御や無料運用を優先するならBeautifulSoupを選択します。

FirecrawlとBrowserbaseの比較

同じくスクレイピング用途で使われるBrowserbaseとの違いも理解しておくと便利です。

項目FirecrawlBrowserbase
主な用途静的コンテンツのクロールブラウザ操作・インタラクティブなスクレイピング
ブラウザ制御内部で自動Puppeteer/Playwrightで完全制御
セッション管理セッションレス永続化・再利用可能
LLM統合Markdown出力でLLMに渡しやすいLangChain等と連携
用途RAG・ナレッジベース構築動的フォーム入力・ログイン処理

単にコンテンツを取得するだけならFirecrawl、動的なフォーム入力やログインが必要ならBrowserbaseが適しています。

実践的なユースケース

1. ドキュメントサイトのRAG構築

// ドキュメントサイト全体をクロールしてRAG構築
const crawlResult = await firecrawl.crawlUrl('https://docs.example.com', {
  limit: 500,
  includePaths: ['/docs/*'],
  scrapeOptions: {
    formats: ['markdown'],
  },
});

// ベクトルDBに保存(省略)
// ...

// ユーザーの質問に回答
const query = 'How do I install the SDK?';
const relevantDocs = await searchVectorDB(query);

const response = await llm.generate({
  prompt: `Answer the question based on the following documentation:\n${relevantDocs}\n\nQuestion: ${query}`,
});

console.log(response);

2. 競合分析

// 競合サイトのブログ記事を定期的に収集
const competitors = ['https://competitor1.com/blog', 'https://competitor2.com/blog'];

const articles = await Promise.all(
  competitors.map(async (url) => {
    const crawlResult = await firecrawl.crawlUrl(url, {
      limit: 50,
      scrapeOptions: {
        formats: ['extract'],
        extract: {
          schema: {
            type: 'array',
            items: {
              type: 'object',
              properties: {
                title: { type: 'string' },
                publishedDate: { type: 'string' },
                tags: { type: 'array', items: { type: 'string' } },
              },
            },
          },
        },
      },
    });

    return crawlResult.data.flatMap((page) => page.extract);
  })
);

console.log('Competitor articles:', articles);

3. ナレッジベース構築

// 社内Wikiをクロールしてナレッジベース構築
const crawlResult = await firecrawl.crawlUrl('https://wiki.internal.com', {
  limit: 1000,
  scrapeOptions: {
    formats: ['markdown'],
  },
});

// ベクトルDBに保存
const documents = crawlResult.data.map((page) => ({
  content: page.markdown,
  metadata: {
    url: page.metadata.url,
    title: page.metadata.title,
  },
}));

await saveToVectorDB(documents);

console.log('Knowledge base built successfully');

Webフックによる通知

大規模クロールでは、完了時にWebフックで通知を受け取れます。

Webフック設定例

// クロールジョブを開始し、完了時に通知
const crawlJob = await app.crawlUrl('https://example.com', {
  limit: 1000,
  webhook: 'https://your-app.com/webhook/crawl-complete',
});

console.log(`Crawl job started: ${crawlJob.jobId}`);

// Webフックエンドポイント(Express例)
app.post('/webhook/crawl-complete', (req, res) => {
  const { jobId, status, data } = req.body;

  if (status === 'completed') {
    console.log(`Crawl job ${jobId} completed with ${data.length} pages`);
    // ベクトルDBに保存等の処理
  }

  res.sendStatus(200);
});

実践メモ: Webフックを使うと、クロール中にAPIをポーリングする必要がなくなり、効率的に処理できます。

料金と制限

Firecrawlは無料プランと有料プランを提供しています(具体的な価格は公式サイトで確認してください)。

無料プラン(目安)

  • 月間リクエスト数: 限定的
  • 並列実行数: 1〜2
  • サポート: コミュニティサポート

有料プラン(目安)

  • 月間リクエスト数: 無制限または大量
  • 並列実行数: 数十〜数百
  • サポート: 優先サポート

注意: 大規模クロールを行う場合は、対象サイトの利用規約とrobots.txtを確認し、過度なリクエストを避けてください。

まとめ

FirecrawlはWebページをLLM最適化されたMarkdownに変換するスクレイピングAPIです。広告・ナビゲーション除去・構造化出力・並列クロールを標準装備し、RAG・エージェントアプリ構築を大幅に加速します。

Firecrawlを選ぶべきケース

  • LLMアプリ(RAG・エージェント)でWebコンテンツを利用したい
  • クリーンなMarkdownをAPIで簡単に取得したい
  • サイト全体を自動クロールしてナレッジベースを構築したい
  • 構造化出力で特定情報を抽出したい
  • スクレイピングのインフラ管理を避けたい

FirecrawlはLangChain・Pinecone・Weaviate等のLLMスタックと統合しやすく、RAGアプリ構築の標準ツールとして広く採用されています。LLMアプリの開発者にとって、Firecrawlは強力な選択肢となります。

関連記事

この技術を体系的に学びたいですか?

未来学では東証プライム上場企業のITエンジニアが24時間サポート。月額24,800円から、退会金0円のオンラインIT塾です。

メールで無料相談する
← 一覧に戻る