1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【解説】LLMを活用したWebスクレイピングの仕組み:CSSセレクター不要でJSONを抽出するPython SDK実装

1
Posted at

Webスクレイピングにおいて最もエンジニアを悩ませるのは、サイトのデザイン改修やCSSクラス名変更に伴う 「セレクターの定期メンテナンス」 です。

従来のスクレイピングは「DOMツリーを どのように(HOW) 探索するか」を記述するものでしたが、LLMを活用したアプローチでは「 何が(WHAT) 欲しいか」を定義するだけで抽出が可能になります。

本記事では、公式Python SDK「scraping-ai」を用いた内部アーキテクチャとデータパイプラインの仕組みを解説します。


内部パイプラインの4ステップ

┌─────────────────┐       ┌─────────────────┐       ┌─────────────────┐
│ 1. スマート取得  │ ─────▶│ 2. Markdown変換  │ ─────▶│ 3. LLMスキーマ  │
│ & 動的レンダリング │       │ (ノイズ除去)     │       │ 照合・推論      │
└─────────────────┘       └─────────────────┘       └─────────────────┘
                                                             │
                                                             ▼
                                                    ┌─────────────────┐
                                                    │ 4. 検証済み      │
                                                    │ 構造化JSON出力  │
                                                    └─────────────────┘

1. スマート取得と動的レンダリング

  • 通常の静的ページは高速に取得します。
  • React、Vue、Next.js等のSPAや動的コンテンツを検知した場合、自動的にクラウド上のヘッドレスブラウザ環境を起動してJavaScriptを実行・描画完了を待機します。

2. Markdownへのノイズ除去変換

生のHTMLには、インラインSVG、広告タグ、CSSスタイル定義などの膨大なノイズが含まれています。

抽出精度とトークン効率を高めるため、HTMLを意味構造を保持した軽量Markdownに変換します。

3. LLMによる意味的スキーマ照合(Semantic Matching)

GPT-4o / Geminiを用いて、指定されたJSON Schemaに基づきデータを抽出します。

CSSクラス名ではなく「文脈と意味」を理解して抽出するため、クラス名が難読化(._3xP9z)されても影響を受けません。

4. JSON Schemaバリデーション

LLMの出力結果を定義されたJSON Schemaで型検証(数値変換、真偽値判定等)し、クリーンな構造化データとしてPython SDKに返却します。


Python SDK(scraping-ai)での実装コード

まず、PyPIからSDKをインストールします。

pip install scraping-ai

1. 同期クライアント(ScrapingAIClient

基本的なデータ抽出は、ScrapingAIClientを使用して実行できます。

from scraping_ai import ScrapingAIClient

# クライアント初期化
client = ScrapingAIClient(api_key="YOUR_API_KEY")

# URLとスキーマを指定して抽出
try:
    data = client.extract(
        url="https://example.com/products/wireless-headphones",
        schema={
            "title": "string",
            "price": "number",
            "in_stock": "boolean",
            "rating": "number"
        }
    )
    print(data.results)
except Exception as e:
    print(f"抽出エラー: {e}")

ポイントは、CSSセレクターを直接指定するのではなく、取得したいデータのスキーマを定義することです。

例えば、以下のように定義します。

{
  "title": "string",
  "price": "number",
  "in_stock": "boolean",
  "rating": "number"
}

このように定義することで、ページ内から意味的に対応する情報を抽出します。

2. 非同期クライアント(AsyncScrapingAIClient

大量のURLを並行処理したい場合は、非同期クライアントを使用します。

import asyncio
from scraping_ai import AsyncScrapingAIClient


async def scrape_product(url: str):
    async with AsyncScrapingAIClient(api_key="YOUR_API_KEY") as client:
        result = await client.extract(
            url=url,
            schema={
                "title": "string",
                "price": "number",
                "in_stock": "boolean"
            }
        )
        return result.results


async def main():
    urls = [
        "https://example.com/products/item-1",
        "https://example.com/products/item-2"
    ]

    tasks = [scrape_product(url) for url in urls]
    results = await asyncio.gather(*tasks)

    print(results)


if __name__ == "__main__":
    asyncio.run(main())

このように asyncio.gather() と組み合わせることで、複数URLに対する抽出処理を並行して実行できます。


応用:LangChain / AIエージェントのツールとしての活用

抽出結果が厳格に型付けされたJSONで返却されるため、LangChainのToolとしてAIエージェントにWeb情報収集能力を付与することも容易です。

例えば、商品情報を取得するToolを以下のように定義できます。

from langchain.tools import tool
from scraping_ai import ScrapingAIClient


client = ScrapingAIClient(api_key="YOUR_API_KEY")


@tool
def fetch_web_product_info(url: str) -> dict:
    """指定URLから商品名、価格、在庫状況を構造化JSONとして抽出するツール"""

    result = client.extract(
        url=url,
        schema={
            "title": "string",
            "price": "number",
            "in_stock": "boolean"
        }
    )

    return result.results

これにより、AIエージェント側からURLを渡すだけで、Webページの商品情報を構造化データとして取得できます。


制約事項と使い分け

LLMを利用したスクレイピングは便利ですが、すべてのケースで従来型のスクレイピングより優れているわけではありません。

BeautifulSoupが適しているケース

  • 単発の学習スクリプト
  • 構造が変わらない社内イントラサイト
  • 完全無料で運用したい場合

Scraping AIが適しているケース

  • 本番運用のデータ収集パイプライン
  • 複数ECサイトの定期的な価格監視
  • Webサイトの変更によるセレクター改修工数を削減したい場合

制限事項

  • SNS(X / Instagram等)のスクレイピングは規約上非対応です。
  • 極めて厳格なアンチボット(Cloudflare Turnstile等)に対する自動ステルス回避率は約85%です。

そのため、従来型のスクレイピングとLLMベースのスクレイピングは、用途に応じて使い分けることが重要です。


無料で試す(200トークン付与)

Scraping AIは無料アカウントから試すことができます。


運営企業・チームについて

Scraping AIは、株式会社SMSデータテックのAIベンチャー子会社である indigodata株式会社 が開発・運営しています。

国内500件以上の受託データ収集実績を持つ「PigData」の知見をベースに、開発者向けセルフサーブ型LLMスクレイピングAPIを提供しています。

詳しくは以下をご覧ください。


まとめ

従来のWebスクレイピングでは、HTML構造やCSSセレクターに依存するため、サイト側のデザイン変更やクラス名変更が発生するたびにコードのメンテナンスが必要でした。

LLMを活用したスクレイピングでは、

  1. Webページを取得
  2. HTMLをMarkdownへ変換してノイズを除去
  3. LLMで指定したスキーマとページ内容を意味的に照合
  4. JSON Schemaで検証
  5. 構造化データとして取得

というパイプラインによって、「どの要素を取得するか」ではなく「何のデータが欲しいか」 を定義したスクレイピングが可能になります。

特に、複数サイトから継続的にデータを収集するシステムでは、セレクターの保守コストを削減できる可能性があります。

一方で、単純かつ安定したHTMLを対象とする場合は、BeautifulSoupなどの従来型スクレイピングのほうがシンプルで低コストです。

用途に応じて、従来型スクレイピングとLLMベースのスクレイピングを使い分けるのが現実的なアプローチと言えるでしょう。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?