大規模 + 非構造化ウェブクローリング

May 20, 2025

実践的なウェブクローリングチュートリアルシリーズの最終セクションへようこそ。従来のレッスンの代わりに、今回は異なるアプローチを取ります。このセクションでは、私が./apps/metascraperディレクトリに構築したHousefly Metascraperを通じて、これまで学んだことを実世界のシナリオでどのように適用するかを示します。

Metascraperは、シンプルな静的HTMLのスクレイピング、JavaScriptでレンダリングされたコンテンツのナビゲーション、APIとの相互作用、クローリング防御の克服といった段階的な学習が、大規模で非構造化された多様で混沌としたウェブを処理できるツールに集約される過程を実証します。

事前にどのようなデータ構造を期待するかを知ることなく、さまざまなウェブサイト全体をクローリングする方法を探求し、AI支援解析動的スキーマ検出、そして崩壊することなく数千(または数百万)のページにスケールするために必要な技術を紹介します。

「非構造化」と「大規模」の真の意味とは?

これまでのセクションでは、しばしば以下を知っていました:

  • どのサイトをターゲットにしているか
  • どのようなデータが欲しいか(例:テーブル、リスト、JSONレスポンス)
  • 何ページ訪問する必要があるか

しかし、大規模非構造化クローリングでは:

  • ウェブサイトは大きく異なります:一部は構造化されており、他は不規則なフォーマットのブログです
  • パスとURLは予測不可能です
  • スキーマは一貫性がないか、存在しません
  • 数千のページを、潜在的に複数のドメインにわたってクローリングしたいのです

次のようなケースを考えてみてください:

  • 学術ウェブサイト全体でデータを収集する研究クローラー
  • トピック特化の知識のためにブログをインデックス化するAIアシスタント
  • パブリックインターネット全体を一般化しなければならない検索エンジン

これがウェブクローリングの最終ボスです。

パート1:大規模クローリングのためのアーキテクチャ

解析を心配する前に、クローラーをスケールアップする方法について話しましょう。

デザインパターン

大規模クローラーを構築するために、アーキテクチャは以下であるべきです:

  • キュー駆動: 保留中のURLを保存するためにメッセージキュー(Redis、RabbitMQ、Kafkaなど)を使用
  • ワーカーベース: クローラーをキューからプルしてジョブを独立して処理するワーカープロセスに分離
  • 重複排除済み: 同じページを2回処理することを避けるために、フィンガープリント化されたインデックス(URLまたはHTMLコンテンツのSHA1など)を維持
  • 再開可能: クラッシュから回復できるようにクロール状態を永続化

最小限のデザイン図:

パート2:2025年の最先端技術

レジデンシャルプロキシ

大規模スクレイピングにおける最も重要な進歩の一つは、レジデンシャルプロキシの使用です。ウェブサイトが簡単に検出してブロックできるデータセンターIPとは異なり、レジデンシャルプロキシは実際の消費者IPアドレス経由でリクエストをルーティングし、スクレイパーを正当なユーザーのように見せます。

AI駆動自律エージェント

2025年の最も革命的な進歩はエージェントスクレイピングです。各サイト形式にスクレイパーをハードコーディングするのではなく:

  • ビジョン機能付きLLMは、以前に見たことのないレイアウトからデータを理解して抽出できます
  • AIエージェントは人間のブラウジングパターンを模倣することで複雑なサイトを自律的にナビゲートできます
  • 適応的解析はコードの更新を必要とせずにレイアウトの変更に自動的に調整されます

パート3:AI支援解析

クリーンなJSONを出力するためにモデルを微調整またはプロンプトエンジニアリング:

{
  "name": "Dr. Maria Lopez",
  "title": "Climate Scientist",
  "organization": "Stanford",
  "topic": "2023 UN Climate Summit, AI in climate modeling"
}

パート4:データの保存、インデックス化、検索

多くの異種データを収集することになります。目標とデータの構造化度に基づいてストレージを選択してください。

ストレージ戦略

  • PostgreSQLまたはSQLite:スキーマがわかっている構造化表形式データに最適(例:記事、価格、タイムスタンプ)。インデックス、外部キー、全文検索(FTS)を使用できます。
  • MongoDBまたはElasticsearch:レコード間でスキーマが異なる可能性があるJSONブロブなどの半構造化または柔軟なデータ形式に最適。
  • S3 / IPFS / ファイルシステム:生のHTMLスナップショット、画像、PDF、大きなバイナリファイルに理想的。メタデータをデータベースに保存し、ファイルの場所にリンクします。

重複排除と以前にクローリングしたアイテムの追跡ができるよう、UUIDまたはURLハッシュを主キーとして使用してください。

検索可能にする

保存後、コンテンツを探索してクエリしたくなります。

オプションには以下が含まれます:

  • PostgreSQL FTS(全文検索):ランキング付きの堅牢なキーワード検索機能を構築するためにtsvectortsqueryを使用。
  • TypesenseまたはMeilisearch:高速インデックス化とファジー検索に最適な軽量でスキーマ柔軟な全文検索エンジン。
  • Elasticsearch:より複雑な検索ユースケースやログに最適で、強力なフィルタリングと分析機能を持つ。

以下のようなフィールドをインデックス化すべきです:

  • タイトル
  • 著者
  • 公開日
  • キーワードまたはタグ(抽出されている場合)
  • メインコンテンツ
  • ドメイン/ソース

埋め込みを使用したセマンティック検索

(キーワードを超えた)より深い理解と検索のために、テキスト埋め込みを使用:

  1. OpenAIのtext-embedding-3-smallbge-small-enなどのオープンソース代替品のようなモデルを使用。
  2. クローリングしたコンテンツを埋め込みベクトルに変換。
  3. 以下のようなベクトルデータベースに保存:
    • Qdrant
    • Weaviate
    • Pinecone
    • FAISS(ローカル/インメモリ使用)

これにより次のようなセマンティッククエリが可能になります:

「寒冷地での自転車に優しい都市開発について誰かが話している記事を見せて。」

クエリ埋め込みを保存された埋め込みと比較することで、クローラーは知識エンジンになります。

メタデータと拡張

最後に、追加のメタデータでデータを拡張:

  • 言語検出(例:langdetectやfastTextを使用)
  • ゼロショットモデルや微調整済み分類器を使用したコンテンツカテゴリ分類
  • 人、組織、場所を抽出するための固有表現認識(NER)
  • コンテンツやソースに基づくジオタグ付け

後でフィルタリングやソートができるよう、これをメインデータと一緒に保存してください。

パート5:検索駆動発見クローラー

大規模クローリングの最も高度なアプローチは、URLから始めることさえしません。代わりに検索クエリから始まります。

SearchXNGやPerplexityなどのツールにインスパイアされた、Metascraperは以下のようなクローラーが示す検索ファーストの戦略を実証します:

  1. シードURLリストではなくトピックまたは質問から始める
  2. 検索エンジンAPIを使用してリアルタイムで関連ページを発見
  3. 検索結果に基づいてクロールキューを動的に構築
  4. 知識を拡張するために引用と参照を知的にフォロー

このアプローチはいくつかの利点を提供します:

  • ターゲット探索:網羅的クローリングではなく、関連情報を含む可能性の高いページのみを訪問
  • 最新の結果:各クロールは現在の検索結果で新しく開始
  • ドメインに依存しない:事前定義されたサイトやURLパターンに制限されない
  • 意図駆動:人間が実際にトピックを研究する方法と整合

Metascraperの検索駆動モードは、検索API、優先順位付けアルゴリズム、コンテキスト認識抽出を組み合わせて、事前にどのURLを訪問するかを知らずに動的に発見されたコンテンツから知識グラフを構築する方法を実証します。

ハッピースクレイピング