ソフトウェアエンジニア必見!mishushakov/llm-scraper徹底解説
一言で言うとね、この llm-scraper は、「どんなウェブページも、AIの力で自動的に、しかも賢く、整理されたデータに変えてくれる魔法のツール」 なんだ!
例えるなら、
醤油ラーメン (既存のスクレイピングツール)
具材(データ)の場所が明確に決まっていて、レシピ(コード)通りに正確に盛り付ける(抽出する)のが得意。でも、新しい具材(ウェブサイトの構造変更)が出てくると、レシピをイチから見直さないといけない手間があるんだ。
味噌ラーメン (mishushakov/llm-scraper)
どんな具材(ウェブページ)が目の前にあっても、全体の味(コンテンツ)を理解して、最適な具材の組み合わせ(必要なデータ)を自動的に判断してくれる。多少具材の配置が変わっても、「あ、このネギはここだな」みたいに柔軟に対応してくれる、すごく賢いシェフ(LLM)が腕を振るってくれるんだ。
豚骨ラーメン (LLM-scraperのさらに進んだ活用)
ただ具材を盛り付けるだけでなく、さらに「この具材は新鮮そうだな」「このチャーシューはもっと厚く切ると美味しいのに」みたいに、具材に対する深い洞察(意味付けや分析)までしてくれる。まさに、データの本質的な価値を引き出してくれるんだ!
つまり、従来のスクレイピングツールが「特定の場所からデータを取る」ことに特化していたのに対して、llm-scraper は「ウェブページ全体の意味を理解して、必要なデータを賢く抽出する」ことに長けているんだよ。AI(LLM)の力を借りることで、人間がウェブページを読んで情報を整理するのと同じような感覚でデータを取得できるのが最大の魅力だね。
俺たちソフトウェアエンジニアにとって、この llm-scraper はまさに救世主のようなツールになり得るんだ!具体的に、こんなシーンで大活躍してくれるよ。
開発・保守コストの削減
従来のスクレイピングは、ウェブサイトのHTML構造(セレクタ)に依存するから、ちょっとしたデザイン変更でもコードの修正が必要だったよね。これがマジで手間だったんだ。
llm-scraper は、LLMがコンテンツの意味を理解して抽出してくれるから、構造変更にめちゃくちゃ強いんだ!「製品名」とか「価格」とか、人間が理解するのと同じような抽象度で指示できるから、修正の手間が格段に減るよ。これは開発コストと保守コストの大幅な削減に直結するんだ。
開発スピードの向上
新しいウェブサイトからデータを取得したいとき、セレクタを調査してコードを書く手間がかなり減るんだ。
「このページから、会社名、住所、電話番号を抽出して」と、まるでAIに話しかけるように指示できるから、プロトタイプ作成や初期開発が超爆速になるよ!
複雑なデータ抽出の実現
従来のスクレイピングでは難しかった、非構造化データからの情報抽出も得意なんだ。例えば、ブログ記事から要約を生成したり、レビュー文から感情を分析したり、なんてことも可能になる。
表形式になっていない、自然言語の文章の中から特定の情報を抜き出す、といった高度な要件にも対応しやすくなるよ。
幅広いユースケースへの対応
競合他社の価格調査、ニュース記事からのキーワード抽出、採用情報ページの自動収集、不動産情報の集約、ECサイトの商品情報収集など、あらゆる分野でのデータ収集に適用できるんだ。
特に、頻繁に構造が変わるようなサイトや、バリエーションが多いサイトからのデータ収集で真価を発揮するよ。
AIとの連携が容易
LLMをバックエンドに利用しているから、抽出したデータをそのままLLMで加工したり、別のAIサービスと連携させたりするのが非常にシームレスに行えるんだ。まさにAIネイティブなデータパイプラインを構築できるってわけだね。
俺としては、特に「開発・保守コストの削減」と「開発スピードの向上」は、日々の業務で実感できる大きなメリットだと思うな。
じゃあ、実際にこの便利なラーメンをどうやって作るか、準備の仕方を見ていこう。
llm-scraper はPythonライブラリとして提供されているから、Pythonが使える環境ならどこでもOKだ。
まだPythonが入ってないなら、まずはPythonをインストールしてね。公式サイトからダウンロードできるよ。
Pythonのパッケージマネージャーであるpipを使って、簡単にインストールできるよ。ターミナル(コマンドプロンプト)を開いて、以下のコマンドを実行するだけ。
pip install llm-scraper
llm-scraper は内部でLLM(大規模言語モデル)を利用するから、そのLLMプロバイダのAPIキーが必要になるんだ。現在は主にOpenAIのGPTシリーズをサポートしているみたいだね。
OpenAI APIキー
OpenAIのウェブサイトでアカウントを作成し、APIキーを発行してね。
APIキーは、環境変数として設定するのがベストプラクティスだよ。こうすることで、コードの中に直接書き込む必要がなくなるから、セキュリティ的にも安心だし、他の人に見られる心配もないね。
# Linux/macOSの場合
export OPENAI_API_KEY="あなたのOpenAI_API_KEY"
# Windowsの場合(コマンドプロンプト)
set OPENAI_API_KEY="あなたのOpenAI_API_KEY"
# Windowsの場合(PowerShell)
$env:OPENAI_API_KEY="あなたのOpenAI_API_KEY"
( 注意
これは現在のセッションのみ有効な設定だよ。永続的に設定したい場合は、OSの環境変数設定方法に従ってね。)
これで準備は万端!いよいよ実戦だ。
さあ、いよいよ美味しいラーメンを作ってみよう!いくつかのパターンでサンプルコードを紹介するね。
まずは一番シンプルな使い方から。とあるブログ記事からタイトルと内容を抽出してみよう。
import os
from llm_scraper import LLMScraper
# 環境変数からAPIキーを読み込む
# os.environ["OPENAI_API_KEY"] = "sk-..." # 環境変数に設定していれば不要
# LLMScraperのインスタンスを作成
# 使用するモデルは 'gpt-3.5-turbo' がデフォルトだけど、変更もできるよ
scraper = LLMScraper(model_name="gpt-3.5-turbo")
url = "https://www.google.com/search?q=AI%E3%81%A8%E3%83%87%E3%83%BC%E3%82%BF%E3%82%B5%E3%82%A4%E3%82%A8%E3%83%B3%E3%82%B9+%E3%83%96%E3%83%AD%E3%82%B0"
# ↑これはGoogle検索結果ページなので、今回は例として別のURLを使うね
# 例えば、どこかのブログ記事のURLを想定してみよう。
# 実際には、例えば、https://zenn.dev/link/articles/xxxxxxxxxxxx のような記事ページを使うよ
# (もし適切なURLがなければ、ダミーとして使うけど、正確な結果は期待できないよ)
# ここでは、例として適当なブログ記事のURLに置き換えて説明するね。
# 実際のウェブページに合わせて以下のような指示を出すと良いよ。
example_blog_url = "https://example.com/blog/2023/ai-data-science-trend" # 仮のURL
# 抽出したいデータのスキーマ(構造)を定義する。
# Pythonの辞書で、キーが抽出したいデータの名前、値がそのデータの説明になるよ。
schema = {
"title": "記事のタイトル",
"main_content": "記事の本文全体",
"author": "記事の著者名"
}
print(f"URL: {example_blog_url} からデータを抽出します...")
try:
# scrape_pageメソッドでデータを抽出!
# scrape_page(url, schema, instruction="具体的な指示文")
# instructionは、より詳細な抽出指示を出したい時に使うよ
data = scraper.scrape_page(example_blog_url, schema=schema, instruction="記事のタイトル、本文、著者名を抽出してください。")
print("\n--- 抽出結果 ---")
for key, value in data.items():
print(f"{key}: {value}")
except Exception as e:
print(f"エラーが発生しました: {e}")
print("指定したURLが適切でないか、OpenAI APIキーが正しく設定されていない可能性があります。")
print("また、無料枠のアカウントではGPT-4などの高性能モデルが使えない場合があります。")
ポイント
schemaで、どんなデータを抽出したいかを自然言語で定義できるのが最大の強み!従来のセレクタ指定とは大違いだよね。
instructionで、さらに詳細な指示を与えることもできるよ。「メインコンテンツから広告部分を除外して」なんてことも可能になるんだ。
次は、検索結果ページやカテゴリページから、複数のアイテム(例えば、複数の記事のURLとそのタイトル)を抽出してみよう。
import os
from llm_scraper import LLMScraper
# scraper = LLMScraper(model_name="gpt-3.5-turbo") # 環境変数にAPIキーがあればこれでOK
# 複数アイテムを抽出したい場合、items_schemaを使うよ。
# 各アイテムがどんな構造をしているかを定義するんだ。
items_schema = {
"title": "ブログ記事のタイトル",
"url": "ブログ記事へのリンクURL",
"summary": "記事の短い要約"
}
# 複数アイテムを抽出する際の全体的なスキーマ
# 'articles'というキーでリスト形式のデータを期待する
collection_schema = {
"articles": {
"type": "array", # リスト形式であることを示す
"items": items_schema # 各要素のスキーマはitems_schemaで定義
}
}
# 例えば、とあるブログサイトのトップページやカテゴリページを想定
# 実際には、このURLにアクセスすると複数の記事のリストが表示されるようなページが良いよ。
example_list_url = "https://example.com/blog/category/ai" # 仮のURL
print(f"URL: {example_list_url} から複数の記事情報を抽出します...")
try:
# scrape_pageにcollection_schemaを渡すことで、複数アイテムの抽出を指示
data = scraper.scrape_page(example_list_url, schema=collection_schema,
instruction="このページに表示されているAI関連のブログ記事について、それぞれのタイトル、URL、短い要約をリスト形式で抽出してください。")
print("\n--- 抽出結果 ---")
if "articles" in data and isinstance(data["articles"], list):
for i, article in enumerate(data["articles"]):
print(f"--- 記事 {i+1} ---")
for key, value in article.items():
print(f"{key}: {value}")
else:
print("記事データが見つからないか、スキーマが正しく適用されていません。")
except Exception as e:
print(f"エラーが発生しました: {e}")
print("指定したURLが適切でないか、OpenAI APIキーが正しく設定されていない可能性があります。")
ポイント
collection_schemaを使って、「このページには、こんな情報を持ったアイテムのリストがあるよ」 とLLMに教えてあげるイメージだね。
"type": "array"と"items": items_schemaの組み合わせが重要だよ。
抽出したデータをさらに加工したり、特定のフォーマットに変換したりすることも可能だよ。
例えば、価格情報から通貨記号を取り除いたり、日付フォーマットを統一したり、なんてこともLLMに指示できるんだ。
import os
from llm_scraper import LLMScraper
# scraper = LLMScraper(model_name="gpt-3.5-turbo")
# ECサイトの商品ページを想定してみよう
example_product_url = "https://example.com/product/awesome-widget-123" # 仮のURL
# 価格を数値として抽出したい場合のスキーマ
schema_with_processing = {
"product_name": "商品の名前",
"price_usd": "商品の価格をドル建ての数値(例: 123.45)として抽出してください。通貨記号やカンマは含めないでください。",
"description_summary": "商品の説明文を200文字以内で要約してください。",
"availability": "商品の在庫状況(例: 在庫あり、在庫なし、残りわずか)"
}
print(f"URL: {example_product_url} から商品情報を抽出します(数値変換・要約付き)...")
try:
data = scraper.scrape_page(example_product_url, schema=schema_with_processing)
print("\n--- 抽出結果 ---")
for key, value in data.items():
print(f"{key}: {value}")
except Exception as e:
print(f"エラーが発生しました: {e}")
print("指定したURLが適切でないか、OpenAI APIキーが正しく設定されていない可能性があります。")
ポイント
スキーマの値(説明文)に、抽出だけでなく加工や変換の指示まで含められるのがすごいところ!「数値として抽出」とか「200文字以内で要約」とか、LLMがその指示を理解して実行してくれるんだ。
これにより、後続のデータ処理の手間を大幅に削減できる可能性があるね。
プロンプトエンジニアリングの考え方
llm-scraper はLLMを使っているので、スキーマやinstructionの記述の仕方が結果に大きく影響するよ。まるでLLMへのプロンプトを書くように、明確で具体的な指示を心がけると良い結果が得られることが多いんだ。
LLMのコストと速度
LLMのAPI利用には費用がかかるし、Webページの読み込み+LLMの処理にはそれなりの時間がかかることがある。大量のページをスクレイピングする場合は、コストと速度のバランスを考慮する必要があるね。
無料枠について
OpenAIなどのLLMプロバイダは無料枠を提供していることが多いけど、モデルの種類や利用量に制限がある場合があるよ。テスト中は無料枠で十分だけど、本格的に使う場合は有料プランへの移行を検討してね。
エラーハンドリング
ネットワークエラー、LLMの応答エラーなど、様々なエラーが起こり得るから、実際のアプリケーションに組み込む際は、適切なエラーハンドリング(try-exceptブロックなど)をしっかり実装しようね。
利用規約の確認
スクレイピング対象のウェブサイトの利用規約を必ず確認して、許可されている範囲で利用するように心がけよう。これはどんなスクレイピングでも共通のルールだよ。