このガイドで、あなたは学ぶだろう:
llm-scraperとは
- ステップ・バイ・ステップのウォークスルーで見る使い方
- コード生成のための使い方
- LLMベースのスクレイピングに代わる主な方法とは?
- 主な限界とその克服法
さあ、飛び込もう!
llm-scraperとは?
llm-scraperは
LLMを使ってあらゆるウェブページから構造化データを抽出するTypeScriptライブラリである。
サイトごとにカスタムパースロジックを書く代わりに、スキーマを定義するだけで、パッケージはLLMを使ってページのコンテンツを分析し、インテリジェントにスキーマを埋めてくれる。
このライブラリが最初にリリースされたのは2024年半ばなので、まだかなり新しい。しかし、GitHub上ではすでに4,000を超えるスターを獲得しており、その人気の速さを示している:
従来のスクレイパーでは破綻しがちな、動的で一貫性のないウェブサイト(eコマースなど)に最適です。そのようなシナリオでは、LLMスクレイピングが輝きます。
llm-scraperが
サポートする主な機能は以下の通りである:
- 複数のLLMプロバイダーとの統合:ローカルモデル(OllamaやGGUFなど)やクラウドプロバイダー(OpenAIやVercel AI SDKなど)と連携。
- スキーマベースのデータ抽出:Zodスキーマを使用して抽出したいデータを定義し、強力な構造と検証を行います。
- 完全な型安全性:TypeScript用に設計されているため、コンパイル時に完全な型チェックを行うことができます。
- Playwrightで構築:ブラウザの制御とページコンテンツの取得にPlaywrightを使用しています。
- ストリーミングのサポート:完全な抽出が完了するのを待つ代わりに、スクレイピング中にオブジェクトをストリーミングできる。
- コード生成:スキーマとターゲットに基づいてスクレイピングコードを動的に生成できます。
- 複数のページ・コンテンツ・フォーマット・オプション:ページコンテンツをLLMに送信する方法を選択できます。
ウェブスクレイピングのためのllm-scraperの使い方
このチュートリアルでは、llm-scraper
ライブラリを使ってAIを搭載したスクレイパーを構築する方法を学びます。対象サイトは、ToScrapeウェブサイトのeコマース商品ページです:
Eコマースサイトのスクレイピングは厄介なので、これは素晴らしい例だ。ページ構造はしばしば変化するし、商品によってレイアウトや情報が異なることもある。そのため、静的な解析ロジックを書くのは難しく、あまり効果的ではない。したがって、AIは間違いなく助けになる。
LLMを搭載したスクレーパーを構築するには、以下の手順に従ってください!
前提条件
このチュートリアルに従うには、以下のものが必要である:
- マシンにインストールされたNode.js
- OpenAI APIキー(またはGroqのような同様のプロバイダーのキー)
- TypeScriptと非同期プログラミングの基本的な理解
ステップ1:プロジェクトのセットアップ
始める前に、最新のLTSバージョンのNode.jsがローカルにインストールされていることを確認してください。インストールされていない場合は、公式サイトからダウンロードしてインストールしてください。
さて、スクレイパー用のプロジェクトを作成し、ターミナルでそのプロジェクトに移動する:
mkdir llm-scraper-project
cd llm-scraper-project
プロジェクト内で以下のコマンドを実行し、空のNode.jsプロジェクトを初期化する:
npm init -y
上記のコマンドで作成したpackage.json
ファイルを開き、以下の内容が含まれていることを確認する:
"type": "module"
プロジェクトのフォルダllm-scraper-projectを
Visual Studio Codeなどのお気に入りのTypeScript IDEで読み込む。
次に、TypeScriptをdev依存としてインストールする:
npm install typescript --save-dev
TypeScriptをインストールした状態で、TypeScriptプロジェクトを初期化する:
npx tsc --init
プロジェクトのフォルダにtsconfig.json
ファイルが現れます。それを開き、以下のように置き換えてください:
{
"compilerOptions": {
"module": "ESNext",
"target": "ESNext",
"moduleResolution": "node",
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"skipLibCheck": true
}
}
さて、プロジェクトにscraper.ts
ファイルを追加しよう:
このファイルにはllm-scraperの
データ抽出ロジックが含まれることになる。スクリプトは非同期のTypeScriptロジックを使用するので、その内部で非同期関数を初期化する:
async function llmScraping() {
// your LLM scraping logic...
}
llmScraping()
素晴らしい!これで完全にセットアップが完了し、AIを搭載したスクレーパーの構築を開始する準備が整った。
ステップ #2: スクレイピングされたライブラリのインストール
llm-scraperは
以下の2つの追加ライブラリに依存して動作する:
- Zod:TypeScriptファーストのスキーマ宣言・検証ライブラリ。
- Playwright:Chromium、Firefox、WebKitブラウザを単一のAPIで自動化するライブラリ。
以下のコマンドでllm-scraperと
一緒にインストールしてください:
npm install zod playwright llm-scraper
Playwrightには、(ブラウザのバイナリなど)追加の依存関係が必要です。それらをインストールしてください:
npx playwright install
さて、scraper.tsで
ZodとPlaywrightをインポートする:
import { z } from "zod"
import { chromium } from "playwright"
import LLMScraper from "llm-scraper"
素晴らしい!これでTypeScriptでLLMのWebスクレイピングを始めるのに必要なライブラリはすべて揃った。
ステップ3:OpenAIのセットアップ
llm-scraperは
OpenAI、Groq、Ollama、GGUFなどいくつかのLLMプロバイダーをサポートしている。今回は OpenAI を使う。もしまだであれば、OpenAIのAPIキーを取得しておいてください。
まず、OpenAIのJavaScriptクライアントをインストールします:
npm install @ai-sdk/openai
そして、それをコードにインポートし、llmScraping()
関数内でLLMモデルを初期化するために使用します:
// other imports...
import { openai } from "@ai-sdk/openai"
// ...
const llm = openai.chat("gpt-4o")
別の統合については、公式のllm-scraper`の
ドキュメントを参照してください。
コードにOpenAIのキーをハードコーディングしないようにするには、dotenvを
インストールしてください:
npm install dotenv
scraper.ts
ファイルにdotenvを
インポートし、dotenv.config()
を呼び出して環境変数をロードする:
// other imports...
import * as dotenv from "dotenv"
// ...
dotenv.config()
これにより、OpenAIのAPIキーのような環境変数を.env
ファイルから読み込むことができます。このように、プロジェクトに.env
ファイルを追加します:
それを開いて、OpenAIのAPIキーを追加する:
OPENAI_API_KEY="<YOUR_OPENAI_KEY>"
置き換える をOpen AIキーの値に置き換えてください。
コード内でこの変数を手動で読み込む必要はない。なぜなら、@ai-sdk/openaiは
自動的にOPENAI_KEY
環境変数を読み込もうとするからです。
驚いた!LLM統合完了
ステップ #4: ターゲットページに接続する
llm-scraperは
、ウェブページのHTMLコンテンツを抽出するために、ブラウザ自動化エンジンとしてPlaywrightに依存しています。始めるには、llmScraping() の
中に以下のコードを追加してください:
- Chromiumブラウザの初期化
- 新しいページを開く
- Playwrightにターゲットページにアクセスするよう指示する。
でそれを達成する:
const browser = await chromium.launch()
const page = await browser.newPage()
await page.goto("https://books.toscrape.com/catalogue/a-light-in-the-attic_1000/index.html")
最後に、ブラウザを閉じてリソースを解放することを忘れないでください:
await page.close()
await browser.close()
このプロセスに慣れていない方は、Playwrightのウェブスクレイピングに関するガイドをお読みください。
ステップ5:データスキーマの定義
さて、llm-scraperは
、特定のデータモデルで定義された構造化データを抽出するために、基礎となるLLMモデルにプロンプトを与え、Playwrightを介してページから抽出されたコンテンツ上で動作する。
そこでZodが登場し、TypeScriptでデータモデルを指定する手助けをする。スクレイピングしたデータのスキーマがどのように見えるべきかを理解するには、ブラウザで対象のサイトを開き、ページのトップレベルを分析することから始める:
ここからは、以下のデータを抽出することに集中してほしい:
- タイトル
- 価格
- 在庫状況
- 数量
- 説明
次に、ページの最後のセクションに移動する:
ここで、あなたは興味を持つだろう:
- UPC(ユニバーサル・プロダクト・コード)
- 製品タイプ
- 税金
- レビュー数
これをすべてまとめると、次のような製品スキーマになる:
const productSchema = z.object({
title: z.string().describe("The name of the product"),
price: z.string().describe("The price of the product, typically formatted as a string like '£19.99'"),
stock: z.string().describe("The availability status of the product, such as 'In Stock' or 'Out of Stock'"),
quantity: z.string().describe("The specific quantity of products available in stock"),
description: z.string().describe("A detailed description of the product, including features and specifications"),
upc: z.string().describe("The Universal Product Code (UPC) to uniquely identify the product"),
productType: z.string().describe("The category or type of the product, such as 'Books', 'Clothing', etc."),
tax: z.string().describe("Information about the applicable tax amount for the product"),
reviews: z.number().describe("The number of reviews the product has received"),
})
ヒントLLMモデルがデータに対して何をすべきかを理解するのに役立ちます。
素晴らしい!これでllm-scraperの
AIスクレイピングタスクを起動する準備ができました。
ステップ #6: スクレイピングタスクの実行
ステップ3で定義したLLMインテグレーションを使って、LLMScraper
オブジェクトを作成する:
const scraper = new LLMScraper(llm)
これはllm-scraper
ライブラリが公開するメインオブジェクトで、AIを使ったスクレイピングタスクを実行する。
そして、次のようにスクレーパーを起動する:
const { data } = await scraper.run(page, productSchema, {
format: "markdown",
})
format
パラメータは、ページ内容がどのようにLLMに渡されるかを定義します。指定できる値は
「html":
ページの生のHTML。"text":
ページから抽出されたすべてのテキストコンテンツ。"markdown":
Markdownに変換されたHTMLコンテンツ。"クリーンアップ":
ページから抽出されたテキストのクリーンアップ版。"イメージ":
ページのスクリーンショット。
注:必要に応じて、コンテンツのフォーマットを制御するカスタム関数を提供することもできます。
新しいAIエージェントはなぜHTMLよりもMarkdownを選ぶのか」ガイドで述べたように、Markdownフォーマットを使用することは、トークンを節約し、スクレイピングプロセスをスピードアップするのに役立つため、賢い選択である。
最後に、scraper.run()
関数は、期待するZodスキーマにマッチするオブジェクトを返します。
完璧!AIを使ったスクレイピング・タスクの完成だ。
ステップ#7:スクレイピングしたデータをエクスポートする
現在、スクレイピングされたデータはJavaScriptオブジェクトに保存されています。データへのアクセス、分析、共有を容易にするには、以下のようにJSONファイルにエクスポートします:
const jsonData = JSON.stringify(data, null, 4)
await fs.writeFile("product.json", jsonData, "utf8")
これには外部ライブラリは必要ない。以下のimportをscraper.ts
ファイルの先頭に追加してください:
import { promises as fs } from "fs"
ステップ8:すべてをまとめる
scraper.tsが
含まれるようになった:
import { z } from "zod"
import { chromium } from "playwright"
import LLMScraper from "llm-scraper"
import { openai } from "@ai-sdk/openai"
import * as dotenv from "dotenv"
import { promises as fs } from "fs"
// load the environment variables from the local .env file
dotenv.config()
async function llmScraping() {
// initialize the LLM engine
const llm = openai.chat("gpt-4o")
// launch a browser instance and open a new page
const browser = await chromium.launch()
const page = await browser.newPage()
// navigate to the target e-commerce product page
await page.goto("https://books.toscrape.com/catalogue/a-light-in-the-attic_1000/index.html")
// define the product schema
const productSchema = z.object({
title: z.string().describe("The name of the product"),
price: z.string().describe("The price of the product, typically formatted as a string like '£19.99'"),
stock: z.string().describe("The availability status of the product, such as 'In Stock' or 'Out of Stock'"),
quantity: z.string().describe("The specific quantity of products available in stock"),
description: z.string().describe("A detailed description of the product, including features and specifications"),
upc: z.string().describe("The Universal Product Code (UPC) to uniquely identify the product"),
productType: z.string().describe("The category or type of the product, such as 'Books', 'Clothing', etc."),
tax: z.string().describe("Information about the applicable tax amount for the product"),
reviews: z.number().describe("The number of reviews the product has received"),
})
// create a new LLMScraper instance
const scraper = new LLMScraper(llm)
// run the LLM scraper
const { data } = await scraper.run(page, productSchema, {
format: "markdown", // or "html", "text", etc.
})
// conver the scraped data to a JSON string
const jsonData = JSON.stringify(data, null, 4)
// populate an output file with the JSON string
await fs.writeFile("product.json", jsonData, "utf8")
// close the page and the browser and release their resources
await page.close()
await browser.close()
}
llmScraping()
ご覧のように、llm-scraperは
JavaScriptベースのスクレイピングスクリプトをわずかなコード行で定義することができます。
このコマンドでスクリプトをTypeScriptからJavaScriptにコンパイルする:
npx tsc
scraper.js
ファイルがあなたのプロジェクトのフォルダに現れます。それを
node scraper.js
スクリプトの実行が終了すると、product.jsonという
ファイルがプロジェクトフォルダに表示されます。
それを開くと、このように表示される:
{
"title": "A Light in the Attic",
"price": "£51.77",
"stock": "In Stock",
"quantity": "22",
"description": "It's hard to imagine a world without A Light in the Attic. This now-classic collection of poetry and drawings from Shel Silverstein celebrates its 20th anniversary with this special edition. Silverstein's humorous and creative verse can amuse the dowdiest of readers. Lemon-faced adults and fidgety kids sit still and read these rhythmic words and laugh and smile and love that Silverstein. Need proof of his genius? Rockabye Rockabye baby, in the treetop Don't you know a treetop Is no safe place to rock? And who put you up there, And your cradle, too? Baby, I think someone down here's Got it in for you. Shel, you never sounded so good.",
"upc": "a897fe39b1053632",
"productType": "Books",
"tax": "£0.00",
"reviews": 0
}
このファイルには、あなたがターゲットとした商品ページに表示された情報が正確に含まれています。ご覧のように、LLMのパワーのおかげで、カスタム解析ロジックを必要とせずにデータが抽出されました。よくやった!
おまけllm-scraper によるコード生成
llm-scraperは
、スキーマが与えられた場合、基礎となるPlaywrightデータ解析ロジックを生成する機能も持っています。これはgenerate()
関数によって可能です。
下のスニペットの例をご覧ください:
const { code } = await scraper.generate(page, productSchema)
ご覧のように、これはPlaywrightページ・オブジェクトとZodスキーマを受け取り、生成されたPlaywrightコードを含む文字列を返します。この場合、出力は
(function() {
function extractData() {
const title = document.querySelector('h1').innerText;
const price = document.querySelector('.price_color').innerText;
const stockText = document.querySelector('.instock.availability').innerText.trim();
const stock = stockText.includes('In stock') ? 'In Stock' : 'Out of Stock';
const quantityMatch = stockText.match(/\d+/);
const quantity = quantityMatch ? quantityMatch[0] : '0';
const description = document.querySelector('#product_description ~ p').innerText;
const upc = document.querySelector('th:contains("UPC") + td').innerText;
const productType = document.querySelector('th:contains("Product Type") + td').innerText;
const tax = document.querySelector('th:contains("Tax") + td').innerText;
const reviews = parseInt(document.querySelector('th:contains("Number of reviews") + td').innerText, 10);
return {
title,
price,
stock,
quantity,
description,
upc,
productType,
tax,
reviews
};
}
const data = extractData();
console.log(data);
})()
そして、この生成されたJavaScriptコードをプログラムで実行し、その結果を解析することができる:
const result = await page.evaluate(code)
const data = schema.parse(result)
データ・
オブジェクトには、前章のステップ#6で作成されたデータと
同じ結果が含まれます。
llm-scraper
LLMスクレイピングの代替手段
LLMを使ったスクレイピングに利用できるライブラリはllm-scraperだけ
ではありません。他にも注目すべき代替ライブラリがある:
- Crawl4AI: AIに対応した高速なウェブクローリングエージェントとデータパイプラインを構築するためのPythonライブラリです。柔軟性が高く、開発者が迅速かつ正確にデプロイできるように最適化されています。Crawl4AIのスクレイピングに関するチュートリアルで、実際に動作する様子をご覧いただけます。
- ScrapeGraphAI: PythonのWebスクレイピング・ライブラリで、LLMと直接グラフ・ロジックを組み合わせて、Webサイトやローカル・ドキュメント(XML、HTML、JSON、Markdownなど)のスクレイピング・パイプラインを構築する。ScrapeGraphAIを使ったスクレイピングのガイドで確認してください。
ウェブスクレイピングのこのアプローチの限界
この記事で使用したターゲットサイトToScrapeは、その名の通り、スクレイピングスクリプトを歓迎するスクレイピングサンドボックスだ。残念ながら、llm-scraperを
実世界のウェブサイトに対して使用する場合、事態はより困難になる可能性が高い…。
なぜか?なぜなら、Eコマース企業やオンライン・ビジネスは、自社のデータがどれほど貴重なものであるかを知っており、その保護のために多大な努力を払っているからだ。たとえそのデータが商品ページで公開されていたとしても同様だ。
その結果、ほとんどのeコマース・プラットフォームは、自動化されたクローラーをブロックするために、アンチボットとアンチスクレイピング対策を実装しています。これらの技術は、llm-scraperと
同じように、Playwrightのようなブラウザ自動化ツールに基づくスクレイパーさえも止めることができる。
悪名高いアマゾンのCAPTCHAのような防御について話しているのだ:
PlaywrightでCAPTCHAを迂回できたとしても、自動化されすぎたリクエストによるIPバンなど、他の課題によってスクレイピング作業が停止される可能性がある。
この時点で、解決策はスクリプトをより複雑にするために際限なく微調整することではない。適切なツールを使うことだ。
PlaywrightをScraping Browserのようなウェブスクレイピング専用に設計されたブラウザと統合することで、すべてがより簡単になります。このソリューションは、スクレイピング用に最適化されたクラウドベースのブラウザです。IPローテーション、自動再試行、高度なアンチボットバイパスメカニズム、さらにはビルトインCAPTCHA解決まで、インフラを自分で管理することなく処理することができる。
スクレイピングブラウザを他のブラウザと同じようにllm-scraperの
Playwrightと統合します。
結論
このブログポストでは、llm-scraperの
特徴と、それを使ってTypeScriptでAIを搭載したスクレイピングスクリプトを構築する方法を学んだ。LLMとの統合のおかげで、複雑で動的なページ構造を持つサイトをスクレイピングすることができます。
説明したように、ブロックされるのを避ける最も効果的な方法は、組み込みのCAPTCHAソルバーと他の多くのアンチボットバイパス機能を備えたBright Dataのスクレイピングブラウザと一緒に利用することである。
このソリューションに基づいて直接AIエージェントを構築することに興味がある方は、Agent Browserをチェックしてみてください。このソリューションは、ブロックされることのないリモートブラウザ上でエージェント主導のワークフローを実行します。無限にスケーラブルで、世界で最も信頼性の高いプロキシネットワークを搭載しています。
今すぐBright Dataの無料アカウントを作成し、データおよびスクレイピングソリューションについてご確認ください!
クレジットカードは必要ありません