← すべての記事

B2B企業データエンリッチメントパイプラインの構築

ディレクトリ、ウェブサイト、ニュースなどから毎日何千もの企業データをエンリッチメントする必要がありますか。毎週壊れることのないB2Bエンリッチメントパイプラインを構築する方法を紹介します。

課題

B2B SaaSプロダクトを構築しているとします。ユーザーが企業名リストをアップロードすると、売上規模、従業員数、技術スタック、資金調達ラウンド、主要な連絡先、最新ニュースなどの整理されたレコードが返されることを期待します。それも数日ではなく数分以内に、かつ正確であることが求められます。

データ自体は存在します。Crunchbase、企業のAboutページ、LinkedInの会社ページ、Google Maps、Glassdoor、地域の登記簿、TechCrunchのアーカイブなどに点在しています。問題は、それらのデータに安定してアクセスすることです。

ソースごとに壊れ方が異なります。Crunchbaseは重いクライアントサイドアプリを提供しており、botを検知すると再レンダリングを発生させます。LinkedInはアグレッシブにrate limitをかけ、セレクタをパッチするよりも早くDOMを変更します(ある人気コミュニティの投稿では、プレーンなPythonスクレイパーはサイトから拒否されるまでに約50プロファイルしか取得できないと報告されています)。企業Webサイトは静的なHTMLから、コンテンツの表示に完全なブラウザを必要とするシングルページアプリケーションまで多岐にわたります。地域ディレクトリは四半期ごとにレイアウトを変更し、国固有のブロックでアクセスを制限します。GroupBWTによる2026年の業界レポートによると、一部の分野ではクローラーの10〜15%がbot検知の変更やDOMドリフトに対応するためだけに毎週の修正を必要としています。

その結果、当初は5つのソースを対象とした綺麗な設計だったエンリッチメントパイプラインも、6か月後には半分壊れたスクレイパー、再試行キュー、そして誰も開かなくなった#scraper-alertsという名前のSlackチャンネルが絡み合う状態になります(以前、自前スクレイパーを維持するための隠れたコストについて記事を書きました)。サポートキューにはデータ品質に関する苦情が積み重なり、チーム内では「Five Scrapers and a Prayer(5つのスクレイパーと祈り)」に社名を変更すべきだという冗談すら出始めます。

アプローチ

スクレイパーのことは一旦忘れてください。エンリッチメントで最も困難なのは抽出ではありません。ルーティングです。どのソースにどのツール、どのproxy、どの再試行ポリシーが必要で、何をもって「正常な」responseとするかを判断することです。

FourAのようなプラットフォームは、対象となる3つのソース種別に直接対応する3つのプロダクトを提供します。

静的HTMLディレクトリおよび登記簿。 ほとんどの地域企業登記簿や多くのレガシーなB2Bディレクトリはサーバーサイドレンダリングされています。これらには、クリーンなIPからの高速で低オーバーヘッドなHTTP requestが必要です。これに対応するのがSingleです。1つのURLを入力し、1つのresponseを出力します。unblocker: trueを追加すれば、プレーンなHTTPクライアントでは完全にブロックされてしまうハンドシェイクレベルの制限を回避できます。SingleはProxy Finderを経由して自動的にルーティングし、responseのトップレベルにproxy ID(r.proxy)を返します。そのため、セッションの継続性が必要な後続の呼び出しでは、これをproxy:"<id>"として渡すことで同じイグジットIPを維持できます。

JavaScriptを多用したSPA。 CrunchbaseやLinkedIn形式のアプリ、さらには中規模企業のサイトであっても、単純なHTTPレスポンスからは必要なデータを返しません。これらはクライアント側でレンダリングされます。そこでBrowserの出番です。完全なブラウザがページを実行してJSを走らせ、レンダリングされたHTML、cookie、スクリーンショットを返します。Singleと同様に、内部でProxy Finder経由でルーティングされるため、ユーザー側での個別の選択ステップは不要です。

検証を伴う混合ソース。 FourAのAPIへのすべてのリクエストはvalidateブロックを受け付けます。特定のステータスコード、headerの一致、またはbody内の部分文字列の一致を必須条件として指定できます。レスポンスがソフトフェイル(認証を求める200ページ、空のデータシェル、「申し訳ありません」というインタースティシャル画面など)の場合、バリデータはそれを拒否します。これにより、パイプラインは同じURLを代わりにBrowser経由でルーティングできます。この単一の機能により、エンリッチメントにおける最もコストのかかるバグ、つまりデータベースにゴミデータを書き込むサイレント障害を排除できます。

単一ソース呼び出しの構造は以下のとおりです。

curl -X POST https://api.foura.ai/api/single \
  -H "X-API-Key: pk_live_..." \
  -d '{
    "url": "https://registry.example.com/company/123",
    "unblocker": true,
    "followRedirects": 5,
    "validate": {
      "status": { "accept": [200] },
      "data":   { "fail":   ["captcha", "blocked", "access denied"] }
    }
  }'

JavaScriptを多用する企業サイト向けのBrowser相当のコードは以下のとおりです。

curl -X POST https://api.foura.ai/api/browser \
  -H "X-API-Key: pk_live_..." \
  -d '{
    "url": "https://www.example-saas.com/about",
    "unblocker": true
  }'

ルーティングロジックはお客様自身のパイプライン側に配置し、信頼性はFourA側が担保します。どのソースにどのツールを割り当てるかはお客様が決定し、FourAはそのツールが確実にリクエストを通すように機能します。

導入結果

パブリックベータ期間中、複数のチームが自社製スクレイパーからFourA経由のパイプラインへと移行する様子を確認してきました。見られる傾向は一貫しています(以下はベータ参加グループ全体で確認された数値に基づく参考データです)。

  • エンリッチメントのレイテンシ: キャッシュされたレジデンシャルルートにおいて、1社あたり3〜6秒から中央値で1.5秒未満に低下
  • サイレント障害率(200応答だがデータが空): データベースに届く前にvalidateブロックでソフトエラーを検知することで、約8%から1%未満に低下
  • スクレイパー保守のエンジニアリング工数: フルタイムエンジニア1〜2名分から、ほぼ通知が来ないSlackチャンネルへと削減
  • 初回成功率: 保護されたディレクトリに対し、unblocker: trueをクリーンなproxy idと組み合わせることで90%台後半まで上昇

もう1つ注目すべき数値があります。初回正解率(正しい会社に対して正しいデータが取れているか)は、初回成功率より約4ポイント下回ることが確認されています。ここからの教訓は、スクレイピングが難しいということではありません。実際にリクエストした対象企業とレコードを突き合わせて検証する処理が依然として不可欠であるということです(このパターンについてはWebスクレイパーが壊れ続ける理由で解説しています)。

重要な数値は、proxyプールの規模やrequest数ではありません。エンリッチメント用endpointが初回の試行で正しいデータを返す割合と、今後6か月間のスクレイパー保守工数グラフの推移です。

主なまとめ

エンリッチメントパイプラインは徐々に破綻していきます。最初に書いたスクレイパーは、火曜日の時点では問題なく動いているように見えます。3つ目のソースを追加する頃には夜11時にセレクタの修正に追われ、10個目になる頃には顧客数の増加に比例して保守負債が膨らみます。20個目に達する頃には、チームの誰も次のソースを担当したがらないため、新しいソースの追加が静かに停止します。

ボトルネックはデータソースそのものではなく、ルーティングにありました。すべてのURLに対して、適切なツール、適切なproxy、適切な検証ルールを毎回選択することです。このレイヤーを一度構築するか、すでにそれを実現している仕組みに任せることで、チームは火曜日にセレクタの破損対応をする代わりに、プロダクトの開発に集中できるようになります。