scraper-builder について
scraper-builder は、Playwright と TypeScript を使ったサイト別スクレーパーのプロジェクトを生成するスキルです。PageObject による構成、Zod でのデータ検証、Docker 設定を備えたコードを作成します。
主な機能
- 01Playwright と TypeScript による生成
- 02ページ単位の PageObject 設計
- 03Zod による抽出データ検証
- 04Docker 対応プロジェクトの生成
- 05agent-browser によるセレクター分析
活用シーン
- 01特定サイト向けスクレーパーの作成
- 02ページ構造から PageObject を生成
- 03ページネーション付きデータの抽出
- 04Docker でのスクレーパー実行
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ jwynia/ agent-skills --skill scraper-builderインストール後、Claude Code で/scraper-builderを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
assets/configs/docker-compose.yml.mddockerfile.mdpackage.json.mdplaywright.config.ts.mdtsconfig.json.mdassets/examples/ecommerce-scraper.mdmulti-page-pagination.mdassets/templates/base-page.ts.mdcomponent.ts.mddata-schema.ts.mdpage-object.ts.mdscraper-runner.ts.mddata/selector-patterns.jsonsite-archetypes.jsonreferences/agent-browser-workflow.mdanti-patterns.mddocker-setup.mdpageobject-pattern.mdplaywright-selectors.mdscripts/generate-page-object.tsscaffold-scraper-project.ts詳細
スクレイパービルダー
Playwright と TypeScript を使用し、PageObject パターンに基づいた完全で実行可能なウェブスクレイパープロジェクトを生成します。このスキルでは、型付きデータ抽出、Docker デプロイ、サイト分析を自動化する agent-browser 連携(オプション)に対応した、サイト固有のスクレイパーを作成します。
このスキルを使用する場面
次の場合にこのスキルを使用してください。
- データ抽出用に、サイト固有のウェブスクレイパーを構築する
- 対象ウェブサイト向けの PageObject クラスを生成する
- Docker に対応した完全なスクレイパープロジェクトのひな形を作成する
- agent-browser を使用してサイトを分析し、セレクターを自動生成する
- ページネーションやデータテーブルなど、再利用可能なスクレイピングコンポーネントを作成する
次の場合はこのスキルを使用しないでください。
- API クライアントを構築する場合(HTTP クライアントライブラリを直接使用してください)
- QA/E2E テストスイートを作成する場合(テストに特化したパターンで Playwright テストランナーを使用してください)
- ドメイン全体を大規模にクロールまたはスパイダーする場合(Crawlee または Scrapy を使用してください)
- 認証の回避や CAPTCHA の解決が必要なサイトをスクレイピングする場合
基本原則
1. PageObject によるカプセル化
対象サイトの各ページを、1 つの PageObject クラスに対応させます。ロケーターはコンストラクターで定義し、スクレイピングのロジックはメソッドに記述します。ページオブジェクトにはアサーションやビジネスロジックを含めず、データを抽出して返す役割に限定します。
2. セレクターの堅牢性
セレクターは、次の順で優先してください。data-testid > id > セマンティック HTML(role、aria-label)> 構造化された CSS クラス > テキストコンテンツ。位置に依存するセレクター(nth-child)や、レイアウトに依存するパスは避けてください。完全な優先順位については、references/playwright-selectors.md を参照してください。
3. 継承よりコンポジション
ページネーション、データテーブル、検索バーなどの再利用可能な UI パターンは、ページオブジェクトがプロパティ経由で組み合わせるコンポーネントクラスとしてモデル化します。継承を使用するのは BasePage のみで、それ以外はすべてコンポジションを使用します。
4. 型付きデータ抽出
スクレイピングしたすべてのデータは、検証のために Zod スキーマを通します。これにより、サイトのマークアップが変更された際のセレクターのずれを、後続の処理ではなく抽出時に検出できます。assets/templates/data-schema.ts.md を参照してください。
5. Docker を前提としたデプロイ
生成されるプロジェクトには、Microsoft 公式の Playwright イメージを使用する Dockerfile と、出力データおよびデバッグ用スクリーンショットのボリュームマウントを含む docker-compose.yml が含まれます。これにより、マシン間で一貫したブラウザー環境を維持できます。
生成モード
モード 1:Agent-Browser による分析
agent-browser を使用して対象サイトを操作し、アクセシビリティツリーのスナップショットを取得して、セレクターを自動的に検出します。エージェントが agent-browser CLI を利用できる場合に推奨されるモードです。
前提条件: agent-browser がまだインストールされていない場合は、まずスキルとして追加してください。
npx skills add vercel-labs/agent-browser
ワークフロー:
# 1. Open the target page
agent-browser open https://example.com/products
# 2. Capture interactive snapshot with element references
agent-browser snapshot -i --json > snapshot.json
# 3. Capture scoped sections for focused analysis
agent-browser snapshot -i --json -s "main" > main-content.json
agent-browser snapshot -i --json -s "nav" > navigation.json
# 4. Test dynamic behavior (pagination, load-more)
agent-browser click @e3
agent-browser wait --load networkidle
agent-browser snapshot -i --json > after-click.json
# 5. Close when done
agent-browser close
スナップショットを使ってエージェントが行うこと:
- 要素の参照(
@e1、@e2など)とそのロールを解析する - セマンティックな用途(ナビゲーション、データ表示、フォーム、アクション)ごとに要素をグループ化する
- データ要素を各フィールド(タイトル、価格、画像など)に対応付ける
- 検出したセレクターを使って PageObject クラスを生成する
- ページネーションと動的読み込みのパターンを特定する
ワークフロー全体のリファレンスについては、references/agent-browser-workflow.md を参照してください。
モード 2:手動での説明
ユーザーが対象サイトのページ構造を説明し、エージェントがその内容をページオブジェクトに対応付けます。エージェントは次のような構成化された質問を行います。
- スクレイピングするページはどれですか? — URL またはページタイプの一覧
- どのデータを抽出しますか? — ページごとのフィールド名と想定される型
- データはどのようにページネーションされますか? — 番号付きページ、「さらに読み込む」、無限スクロール、または単一ページ
- 既知のセレクターはありますか? — ユーザーがすでに把握している CSS セレクター、data-testid 値、または XPath
その後、エージェントは次の処理を行います。
- 説明を
data/site-archetypes.jsonのサイトアーキタイプに照合する - クラス名と役割を含むページオブジェクトマップを提案する
- ユーザーが計画を確認した後にコードを生成する
モード 3:プロジェクト一式のスキャフォールド
スキャフォルダーのスクリプトを使用して、実行可能なプロジェクト一式を一度に生成します。
deno run --allow-read --allow-write scripts/scaffold-scraper-project.ts \
--name "my-scraper" \
--url "https://example.com" \
--pages "ProductListing,ProductDetail" \
--fields "title,price,image_url,description"
すべてのソースファイル、設定、Docker セットアップ、すぐに実行できるエントリーポイントを含むプロジェクトが生成されます。すべてのオプションについては、「スクリプトリファレンス」セクションを参照してください。
クイックリファレンス
| カテゴリ | アプローチ | 詳細 |
|---|---|---|
| フレームワーク | Playwright | @playwright/test ではなく、playwright パッケージを使用 |
| 言語 | TypeScript | Strict モード、ES2022 をターゲットに設定 |
| パターン | PageObject | ページごとに 1 つのクラスを作成し、コンポーネントを組み合わせます |
| セレクター | 堅牢性重視 | data-testid > id > role > CSS class > text |
| 待機戦略 | 自動待機 | Playwright 組み込み機能に加え、ナビゲーションでは networkidle を使用 |
| 検証 | Zod | 各ページオブジェクトの出力型にスキーマを定義 |
| 出力 | JSON + CSV | ストレージユーティリティで設定可能 |
| Docker | 公式イメージ | mcr.microsoft.com/playwright:v1.48.0-jammy |
| リトライ | 指数バックオフ | デフォルトは 3 回、設定で変更可能 |
| スクリーンショット | エラー発生時 | デバッグ用に screenshots/ に保存 |
生成プロセス
スクレイパーを生成するときは、次の手順に従ってください。
ステップ 1:要件を確認する
ユーザーに次の情報を確認します。
- 対象サイトの URL
- 抽出するデータ項目
- 想定されるページ数/項目数
- 希望する出力形式(JSON、CSV、または両方)
- Docker によるデプロイが必要かどうか
ステップ 2:サイトを分析する
モード 1(agent-browser)またはモード 2(手動での説明)を使って、次の内容を把握します。
- ページ構造とナビゲーションフロー
- データ要素の位置とセレクター戦略
- ページネーションまたは無限スクロールのパターン
- 動的コンテンツの読み込み動作
ステップ 3:Page Object マップを設計する
次の項目を一覧にした計画を作成します。
- 各 PageObject クラスと URL パターン
- 必要なコンポーネントクラス(Pagination、DataTable など)
- ページごとのデータスキーマのフィールドと型
- ページ間のスクレイパーのナビゲーションフロー
ステップ 4:計画を提示する
コードを生成する前に、ユーザーに Page Object マップを提示します。クラス名、フィールド名、実行フローを含めます。確認を待ちます。
ステップ 5:コードを生成する
assets/templates/ のテンプレートを基盤として使用します。
base-page.ts.md— BasePage 抽象クラスpage-object.ts.md— サイト固有のページオブジェクトcomponent.ts.md— 再利用可能なコンポーネントscraper-runner.ts.md— オーケストレーターdata-schema.ts.md— Zod 検証スキーマ
ステップ 6:納品する
次の内容を含むプロジェクト一式を提供します。
- すべてのソースファイル
assets/configs/の設定ファイル- 実行方法を説明する README
- Docker セットアップ(明示的に除外するよう指定された場合を除く)
コードパターン
BasePage
navigate()、waitForPageLoad()、screenshot()、getText() ヘルパーを提供する抽象クラスです。すべてのページオブジェクトはこのクラスを継承します。
export abstract class BasePage {
constructor(protected readonly page: Page) {}
async navigate(url: string): Promise<void> { /* ... */ }
async screenshot(name: string): Promise<void> { /* ... */ }
}
参照:assets/templates/base-page.ts.md
PageObject
ロケーターを読み取り専用プロパティとして持ち、型付きデータを返すスクレイプメソッドと、複数ページのフローに対応するナビゲーションメソッドを備えた、サイト固有のクラスです。
export class ProductListingPage extends BasePage {
readonly productCards: Locator;
readonly nextButton: Locator;
async scrapeProducts(): Promise<Product[]> { /* ... */ }
async goToNextPage(): Promise<boolean> { /* ... */ }
}
参照:assets/templates/page-object.ts.md
Component
親ロケーターのスコープを受け取り、データ抽出メソッドを提供する再利用可能な UI パターン(Pagination、DataTable)です。
export class Pagination {
constructor(private page: Page, private scope: Locator) {}
async hasNextPage(): Promise<boolean> { /* ... */ }
async goToNext(): Promise<void> { /* ... */ }
}
参照:assets/templates/component.ts.md
ScraperRunner
ブラウザーを起動し、ページオブジェクトを作成して、ページを順に処理しながらデータを収集し、スキーマで検証して、出力を書き込むオーケストレーターです。
export class SiteScraper {
async run(): Promise<void> {
const browser = await chromium.launch();
const page = await browser.newPage();
// navigate, scrape, validate, write
}
}
参照:assets/templates/scraper-runner.ts.md
DataSchema
スクレイピングしたレコードを検証する Zod スキーマです。抽出時にセレクターのずれや不正な形式のデータを検出します。
export const ProductSchema = z.object({
title: z.string().min(1),
price: z.number().positive(),
});
参照:assets/templates/data-schema.ts.md
アンチパターン
| アンチパターン | 問題 | 解決策 |
|---|---|---|
| モノリス型スクレイパー | すべてのスクレイピングロジックが1つのファイルにある | ページごとにPageObjectクラスへ分割する |
| スリープ待機 | setTimeout/固定の遅延を使用する | Playwrightの自動待機とnetworkidleを使用する |
| 未検証のパイプライン | 出力にスキーマ検証がない | すべてのデータ型にZodスキーマを追加する |
| セレクターくじ | 壊れやすい位置ベースのセレクター | 耐障害性のあるセレクター階層を使用する |
| サイレント失敗 | エラーをログに記録せずに握りつぶす | 失敗をログに記録し、デバッグ用スクリーンショットを保存する |
| 無制限クローラー | リクエスト間に遅延がない | 設定可能なリクエスト遅延を追加する |
| 設定のハードコード | URLやセレクターがコード内にある | 環境変数と設定ファイルを使用する |
| リトライロジックなし | リクエストごとの試行が1回だけ | 指数バックオフを実装する |
例と修正を含む詳細な一覧については、references/anti-patterns.mdを参照してください。
スクリプトリファレンス
scaffold-scraper-project.ts
完全なスクレイパープロジェクトを生成します。
deno run --allow-read --allow-write scripts/scaffold-scraper-project.ts [options]
Options:
--name <name> Project name (required)
--path <path> Target directory (default: ./)
--url <url> Target site base URL
--pages <pages> Comma-separated page names (e.g., ProductListing,ProductDetail)
--fields <fields> Comma-separated data fields (e.g., title,price,rating)
--no-docker Skip Docker setup
--no-validation Skip Zod validation setup
--json Output as JSON
-h, --help Show help
Examples:
# Scaffold a product scraper
deno run --allow-read --allow-write scripts/scaffold-scraper-project.ts \
--name "shop-scraper" --url "https://shop.example.com" \
--pages "ProductListing,ProductDetail" --fields "title,price,image_url"
# Minimal scraper without Docker
deno run --allow-read --allow-write scripts/scaffold-scraper-project.ts \
--name "blog-scraper" --no-docker
generate-page-object.ts
既存のプロジェクト向けに、単一のPageObjectクラスを生成します。
deno run --allow-read --allow-write scripts/generate-page-object.ts [options]
Options:
--name <name> Class name (required)
--url <url> Page URL (for documentation comment)
--fields <fields> Comma-separated data fields
--selectors <json> JSON map of field to selector
--with-pagination Include pagination methods
--output <path> Output file path (default: stdout)
--json Output as JSON
-h, --help Show help
Examples:
# Generate a page object with known selectors
deno run --allow-read --allow-write scripts/generate-page-object.ts \
--name "ProductListing" --url "https://shop.example.com/products" \
--fields "title,price,rating" \
--selectors '{"title":".product-title","price":".product-price","rating":".star-rating"}' \
--with-pagination --output src/pages/ProductListingPage.ts
# Quick generation to stdout
deno run --allow-read scripts/generate-page-object.ts \
--name "SearchResults" --fields "title,url,snippet"
テンプレートとリファレンス
テンプレート(assets/templates/)
| テンプレート | 目的 |
|---|---|
base-page.ts.md | ナビゲーション、スクリーンショット、テキストヘルパーを備えた抽象BasePage |
page-object.ts.md | ロケーターとスクレイピングメソッドを備えた、サイト固有のページオブジェクト |
component.ts.md | 再利用可能なコンポーネント:Pagination、DataTable |
scraper-runner.ts.md | オーケストレーター:ブラウザーの起動、反復、収集、出力 |
data-schema.ts.md | スクレイピングしたデータを検証するZodスキーマ |
設定(assets/configs/)
| 設定 | 目的 |
|---|---|
dockerfile.md | 公式Playwrightイメージを使用したマルチステージDockerfile |
docker-compose.yml.md | データ/スクリーンショットのボリュームをマウントするサービス |
tsconfig.json.md | ES2022をターゲットにした厳格なTypeScript設定 |
package.json.md | playwright、zod、tsxの依存関係 |
playwright.config.ts.md | スクレイパーに特化したPlaywright設定 |
リファレンス(references/)
| リファレンス | 目的 |
|---|---|
pageobject-pattern.md | スクレイピング向けに適用したPageObjectパターン |
playwright-selectors.md | セレクター戦略と耐障害性の階層 |
docker-setup.md | Dockerの設定とデプロイ |
agent-browser-workflow.md | エージェントブラウザーによる分析ワークフロー |
anti-patterns.md | 詳細なアンチパターン一覧 |
例(assets/examples/)
| 例 | 目的 |
|---|---|
ecommerce-scraper.md | 複数ページの商品スクレイパーの完全な手順 |
multi-page-pagination.md | ページネーションの処理戦略 |
データファイル(data/)
| ファイル | 目的 |
|---|---|
selector-patterns.json | UI要素の種類ごとに整理した一般的なセレクター |
site-archetypes.json | 典型的なページとフィールドを含むウェブサイト構造の類型 |
やり取りの例
ユーザー:「オンライン書店向けのスクレイパーが必要です。カタログページから書籍のタイトル、著者、価格、評価を取得したいです。」
エージェントのワークフロー:
site-archetypes.jsonを確認 —ecommerceの類型に一致- ページオブジェクトの構成を提案:
BookListingPage— ページネーション付きのカタログBookDetailPage— 個別の書籍ページ(詳細のスクレイピングが必要な場合)Paginationコンポーネント — 共通のページネーション処理
- フィールドのマッピングとともに計画を提示:
title→[itemprop="name"]または.book-titleauthor→[itemprop="author"]または.book-authorprice→[itemprop="price"]または.pricerating→.star-ratingまたは[data-rating]
- 確認後、スキャフォールドスクリプトまたは手動のコード生成で作成
Book型向けのDocker設定とZodスキーマを含むプロジェクトを提供
統合
このスキルは以下と連携します。
- typescript-best-practices — 生成コードで使用される TypeScript のコーディングパターン
- devcontainer — 生成プロジェクトの開発コンテナーのセットアップ
- agent-browser — サイト分析とセレクターの特定(外部ツール)
このスキルで対応しないこと
このスキルでは、以下のことは行いません。
- 認証やログイン画面を回避すること
- CAPTCHA やボット検知を解決すること
- JavaScript のみの出力を生成すること(常に TypeScript を使用します)
- ドメイン全体を巡回するクローラーを生成すること
- robots.txt に違反するスクレイパーを作成すること
- レート制限のある API を扱うこと(API の作業には HTTP クライアントを使用してください)
- テストスイートを生成すること(QA には Playwright のテストパターンを使用してください)