スクレイピング

LLM抽出 vs セレクター: モデルにページを読ませるべき時

大規模言語モデルに18の実際のニュースページからフィールドを抽出させ、各ページ自身の構造化データと照合してスコアを算出しました。精度、コスト、そして使うべき場面について。

Chris Collins

Chris Collins

2026年9月28日 · 3 分で読める

20年間、ウェブページからデータを抽出するとはセレクタを書くことを意味していた。要素を見つけ、テキストを取り出し、サイトが変わるたびに直す。大規模言語モデルはこれとは違う取引を提示する。モデルにページを渡し、欲しいフィールドを説明すれば、構造化データが返ってくる。セレクタを書く必要もなく、リデザインで壊れることもない。

この取引は本物だが、代償がある。コスト、速度、失敗のパターンだ。この3つは、パイプラインをこれ中心に作り直す前に測っておく価値がある。そこで実際に測定した。本稿では、実際のページに対する小規模で正直なテストと、外れた結果が何を示したか、規模を拡大した際のコスト、そして抽出パイプラインの中でモデルがどこに位置づけられるべきかを報告する。

主な要点

  • 18件の実際のニュース記事に対して、大規模なClaudeモデルは見出しを全18件正確に抽出し、日付は18件中17件、著者リストは18件中14件を正しく抽出した(各ページ自体の構造化データと照合して採点)。
  • 大半の「不一致」はモデルの誤りではなかった。著者情報が食い違ったすべてのページで、構造化データには汎用のプレースホルダーが入っていた。そのうち2件では、モデルは実際にページに表示されていた署名を報告していた。
  • モデルは何も捏造しなかった。返された見出しと著者はすべてページのテキストに存在していた。それでも1件、実際の誤りを犯した。写真家を著者として記載してしまったのだ。
  • リスト価格でページあたり約1.9セント、所要時間は中央値2.4秒だった。構造化データの解析はほぼ無料で、ミリ秒単位で完了する。
  • セレクタの維持コストが高い場合、たとえば多数の異なるサイトテンプレートがある場合や、構造化データの出典がないフィールドの場合にモデルを使い、返された内容はすべて検証すること。

テストした内容

設定値
ページ1つの大手ニュース発行元のセクショントップから集めた、実際の記事18件。2026年9月28日に収集
モデルへの入力ページの可視テキスト。ナビゲーションやその他のページ付随要素を含み、平均約8,700文字
フィールド見出し、ページに表示された公開日、著者名
モデルClaude Opus 5、低エフォート設定、出力を制約するJSONスキーマ付き
正解データ同じページ自体のJSON-LD構造化データ
採点見出しと日付は完全一致が必要。著者リストは集合として一致するか

正解データとして採用したのは、意図的にHTMLの解析をやめようで扱った類のデータ、つまり発行元が検索エンジン向けに埋め込む構造化データだ。通常これは正しい。ただし今回わかったのは、必ずしもそうではないということだ。

結果

指標結果
見出しの正解18件中18件
日付の正解18件中17件
著者の正解18件中14件
抽出値がページテキスト内で見つかった見出し18件中18件、著者リスト18件中18件
ページあたりのトークン数入力約3,380、出力66
レイテンシ中央値2.4秒、範囲1.8秒から10.6秒
実行全体のコストリスト価格で $0.33、ページあたり約1.9セント

不一致こそが興味深い部分だった

見出しの数値はモデルの実力を過小評価し、正解データを過大評価している。それぞれの不一致を見ていくと。

  • あるオピニオンコラム。 構造化データには著者として汎用のスタッフライタープレースホルダーが記載されていた。可視の署名には実際のコラムニストの名前があった。モデルはそのコラムニストを返した。
  • あるワイヤー配信記事。 構造化データはここでも汎用プレースホルダーを示していたが、可視の署名には「Staff and agencies」とあった。モデルはページに表示されていた通りの内容を返した。
  • ニュースレター登録ページが集合に紛れ込んでいた。著者も日付も表示されていなかった。それでも構造化データは汎用の著者と日付を提供していたが、モデルは両方のフィールドを捏造せずに空のままにした。
  • あるフォトエッセイ。 構造化データは同じ汎用プレースホルダーを示していた。ページには写真のクレジットとして特定の写真家名が記載されており、モデルはその写真家を著者として返した。これは正真正銘の誤りである。

つまり不一致のあった4件のページのうち、2件は正解データが可視ページより不正確だったことを反映しており、1件はモデルが正しく推測を避けたケースであり、1件が実際の誤りだった。これによって問うべき問いが変わってくる。構造化データは強力な既定の選択肢ではあるが、絶対的な正解とは限らない。可視ページを読むモデルは、構造化データが誤っている箇所を捉えられる一方、目にした内容を誤って読み取ることも時にはある。

規模を拡大した際のコスト

このテストは、Claude Opus 5のリスト価格である入力100万トークンあたり$5、出力100万トークンあたり$25で、18ページに対して$0.33かかった。これはページあたり約1.9セントに相当し、100万ページあたりでは約$18,600になる。Anthropicのバッチ APIは、待てる作業についてはこれらのトークン価格を半額にする。より小型のモデルはトークンあたりさらに安く、Claude Haiku 4.5は$1と$5と記載されているが、今回はテストしていない。あなたのページにおける精度は、仮定するのではなく測定すべきものだ。

レイテンシも重要だ。ページあたり中央値2.4秒で、時折外れ値が生じるという状況は、モニタリングやエンリッチメントには十分だが、大量のクロールにおいては実質的な制約となる。JSON-LDの解析やセレクタの実行はミリ秒単位で完了し、フェッチ以外のコストは実質ゼロだ。こうした抽出コストは収集コストの上に積み重なるものであり、だからこそクリーンなレコードあたりのコストには両方を含めるべきなのだ。

どちらを使うべきか

状況最適なアプローチ
ページがJSON-LDや埋め込みJSONでフィールドを公開している構造化データを解析する
1つまたは少数のサイトテンプレートからの大量データセレクタまたは構造化データ、検証付きで
それぞれ独自のテンプレートを持つ多数の異なるサイト検証付きのモデル。場合によっては後で再利用するセレクタをモデルに生成させる
利用規約、資格条件、仕様など、文章にしか存在しないフィールドモデル
ページで構造化データの検証が失敗する場合フォールバックとしてのモデル
低ボリューム、高価値、頻繁なレイアウト変更モデル

最も強力なパイプラインはこれらを組み合わせている。まず構造化データを解析し、必須フィールドが欠けているか検証に失敗した場合にモデルにフォールバックし、各レコードをどちらの手法で生成したか記録する。これは構造化データについて説明したのと同じフォールバックチェーンのパターンだ。1つのサイトテンプレートが数千ページをカバーしている場合には、モデルに一度だけセレクタを提案させ、そのセレクタを各ページで安価に実行し、壊れたときのためにモデルを待機させておくという方法も有効だ。

モデルを安全に使う

4つの実践により、モデルによる抽出を印象的なものから信頼できるものへと変えることができる。

出力を制約する。 JSONスキーマにより、モデルは求めたフィールドと型を返すようになる。それでも停止理由は必ず確認すること。拒否や途中終了した応答には解析できるものが何もないからだ。ページに表示されていないフィールドは空のままにするようモデルに指示すること。今回のテストではまさにその通りに動作した。

根拠付けを確認する。 名前、見出し、商品名など、ページに存在すべき抽出済み文字列はすべて、ページテキスト内で見つかるべきだ。これは捏造された値を捕捉する安価なチェックだ。ただし、写真家のケースが示すように、実在する名前が誤ったフィールドに結びついているケースは捕捉できない。つまりこれはフィルターであって、証明ではない。

人間によるレビュー用にサンプリングする。 毎週小規模なランダムサンプルを抽出し、人間がページを読んだ結果と照合して採点し、フィールドごと、サイトごとの精度を時系列で追跡すること。

ページテキストを信頼できない入力として扱う。 ページは他の誰かによって書かれている。ウェブコンテンツに対してモデルを使うのは抽出のためだけにとどめ、ページの内容にアクションを引き起こさせず、モデルへの指示とページの内容は分離して保つこと。

以下は、実際に使用した抽出呼び出しと、それに続く根拠付けチェックである。

import Anthropic from "@anthropic-ai/sdk";

const client = new Anthropic();

const SCHEMA = {
  type: "object",
  properties: {
    headline: { type: "string" },
    date_published: { type: "string", description: "YYYY-MM-DD, as shown on the page" },
    authors: { type: "array", items: { type: "string" } },
  },
  required: ["headline", "date_published", "authors"],
  additionalProperties: false,
};

export async function extractArticle(pageText) {
  const response = await client.beta.messages.create({
    model: "claude-opus-5",
    max_tokens: 2000,
    betas: ["server-side-fallback-2026-07-01"],
    fallbacks: "default",
    output_config: { effort: "low", format: { type: "json_schema", schema: SCHEMA } },
    messages: [{
      role: "user",
      content:
        "Below is the visible text of a news article web page, including navigation and other page furniture. " +
        "Extract the article's headline exactly as written, its publication date as shown on the page (YYYY-MM-DD), " +
        "and the author names. Leave a field empty if the page does not show it.\n\n<page>\n" + pageText + "\n</page>",
    }],
  });
  if (response.stop_reason === "refusal") return null;
  const text = response.content.filter((b) => b.type === "text").map((b) => b.text).join("");
  return { record: JSON.parse(text), usage: response.usage };
}

// Grounding check: every extracted string must actually appear in the page text.
export function grounded(record, pageText) {
  const norm = (s) => s.replace(/[‘’]/g, "'").replace(/[“”]/g, '"').replace(/\s+/g, " ").toLowerCase();
  const page = norm(pageText);
  return {
    headline: page.includes(norm(record.headline)),
    authors: record.authors.every((a) => page.includes(norm(a))),
  };
}

入力そのものもモデルと同じくらい重要だ。モデルはページに実際に含まれる内容しか抽出できないため、ブロックページ、同意画面、空のシェルは、誤った内容を自信満々に抽出する結果を生む。抽出する前に、フェッチしたものを検証すること。これはサイレント失敗率で扱った通りであり、必要なページのバージョンを持つマーケットからフェッチすること。

このテストの限界

1つの発行元からの18ページというのは小さなサンプルであり、決定的であることよりも正直であることを選んだ結果だ。ニュース記事も比較的簡単なケースである。見出しは明確で、署名は可視で、日付もラベル付けされている。バリエーション、価格、在庫情報を持つ商品ページや、他言語のページでは挙動が異なるだろう。今回テストしたのは1つのモデルの1つのエフォートレベルのみだ。この手法は自分のページで簡単に再現できるものであり、自分のページこそが唯一意味のあるベンチマークなのだ。

結論

ページを読むモデルは、すべての見出しを正確に抽出し、何も捏造せず、いくつかのケースではページ自体の構造化データよりも忠実にページの内容を報告した。同時に、著者を1回誤って特定し、コストは1セントの何分の一ではなくセント単位であり、ミリ秒ではなく秒単位の時間を要した。

これにより、セレクタが苦手とする抽出の部分、すなわち多数のテンプレート、文章のみのフィールド、構造化データが失敗した際のフォールバックにおいて、モデルは強力なツールとなる。だが、構造化データが存在する場合にそれを置き換えるものではない。ページが公開している内容は解析し、公開していない部分にはモデルを活用し、両方を検証し、どちらを使用したかを記録すること。

出典と参考文献

  • Anthropic, Pricing。テスト時点でのモデルおよびバッチAPIの価格。
  • Schema.org, NewsArticle。
  • Shifterによって2026年9月28日に、公開アクセス可能な18件のニュース記事を対象に、上記のコードを用いて実施したテスト実行。

始める準備はできていますか?

Shifterのレジデンシャルプロキシをお試しください。IP 205M+件、195+カ国、$0.10/GBから。

始める