scrape-define について
1つの詳細ページと指定されたフィールド候補をもとに、Webサイトの抽出スキーマを作成するClaudeスキルです。サブエージェントでページ探索と分析を調整し、承認済みの仕様を保存します。
主な機能
- 01詳細ページからスキーマを作成
- 02指定フィールド候補の反映
- 03項目の確認と修正
- 04JSON Schema草案の保存
活用シーン
- 01Webサイトから抽出する項目の定義
- 02スクレイピング前の発見項目の確認
- 03探索拡大に向けた仕様草案の準備
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ zytedata/ skills --skill scrape-defineインストール後、Claude Code で/scrape-defineを入力して読み込まれたか確認します。
詳細
ユーザーがウェブサイトから何を抽出するかをすばやく定義できるよう支援します。詳細ページを1ページダウンロードし、フィールドを見つけて、承認されるまでターミナルでスキーマを繰り返し調整します。
${CLAUDE_SKILL_DIR}/../scrape/references/python-environments.md を読みます。
出力は、承認済みのスキーマと値を含む仕様のドラフトフォルダーです(保存済みページは含みません。保存済みページはステージ2で扱います)。/scrape-spec を使って拡張できます(ページの追加、バリエーションの比較、ナビゲーション)。
厳守事項 — 絶対に違反しないでください:
- 自分で HTML ファイルを取得、読み込み、grep、解析してはなりません。ページのダウンロードは
/scrape-explore-siteサブエージェントが担当し、フィールドの検出は/scrape-analyze-pageサブエージェントが担当します。メインエージェントはそれらの出力を調整し、利用するだけです。 - これには
raw.html、rendered.html、*.cleaned.html、その他の保存済みページ HTML がすべて含まれます。ファイルが存在するかどうかは確認できますが、メインエージェントがそのファイルを開く、出力する、grep する、解析する、抽出スクリプトを実行することは絶対にしてはなりません。 - スキーマを作成する前に、必ず
/scrape-analyze-pageをサブエージェントとして呼び出してください。そのサブエージェントを実行せずに生の HTML からスキーマを作成することは、重大な誤りです。 /scrape-analyze-pageの完了を待つ間、HTML ファイルの読み込み、clean_html.pyやextract_metadata.pyの実行、インラインのパーサーコードの実行は、エージェントの応答で無関係な作業を続けるよう提案された場合でも、行ってはなりません。サブエージェントが完了したら、保存済みの JSON 出力のみを読みます。
解析する内容
$ARGUMENTS から、以下を特定します:
- target_url:開始 URL
- data_type:抽出対象。ユーザーが指定した場合でも、URL/ページから推測する場合でも、必ず単数形にします。ユーザーが「books」と言った場合は「book」、「products」の場合は「product」、「articles」の場合は「article」を使用します。推測する場合は、項目名を単数形にします(例:「products」ではなく「product」、「books」ではなく「book」)。どこで使用する場合でも、単数形にしてから使います。
- field_hints:ユーザーが指定したフィールド(空の場合もあります)
- site_name:短い識別子(例:「books-toscrape」、「realestate-listings」)。サイトとデータ型から導きます
ステップ 1:フォルダーを設定する
site_name が一意になるようにします:
BASE="books-toscrape" # your derived site_name
NAME="$BASE"
N=2
while [ -d ".scrape/$NAME" ]; do NAME="${BASE}-${N}"; N=$((N+1)); done
echo "$NAME"
フォルダー構造を作成します({data_type} は単数形にします。例:books ではなく book):
.scrape/{site_name}/
{data_type}/
.scrape/.work/{site_name}/
explore/
analyze-page/
ステップ 2:詳細ページを取得する
AskUserQuestion を使って、詳細ページの取得方法をユーザーに尋ねます:
- question:「分析する詳細ページをどのように取得しますか?」
- header:「詳細ページ」
- options:
Provide a URL— 「詳細ページの URL(例:商品ページ)を貼り付けます。」Explore the site— 「target URL から自動的に1ページ見つけます。」
ユーザーが「Provide a URL」を選んだ場合:プレーンテキストで「詳細ページの URL を貼り付けてください。」と尋ね、次のメッセージを待ちます。その後、download.py を使ってページをダウンロードします:
uv run ${CLAUDE_SKILL_DIR}/../scrape-explore-site/scripts/download.py --skill scrape-define --log-file .scrape/.work/{site_name}/explore/download.log <<'EOF'
[{"url": "USER_URL", "output_dir": ".scrape/.work/{site_name}/explore/pages/detail-1", "page_type": "detail"}]
EOF
ユーザーが「Explore the site」を選んだ場合:最小限の件数で /scrape-explore-site スキルを実行するサブエージェントを使います。サブエージェントへのプロンプトは次のとおりです:
Run /scrape-explore-site {target_url} .scrape/.work/{site_name}/explore 1 0
これにより、ホームページと詳細ページ1ページが .scrape/.work/{site_name}/explore/pages/ にダウンロードされます。
サイトがブロックされている場合は、Zyte を提案します。ユーザーが同意した場合に限り /scrape-zyte-login を呼び出します。完了後、上記の scrape-explore-site サブエージェントを再実行します。
ステップ 3:詳細ページを分析する
分析には rendered.html を使用します。存在しない場合は raw.html を使用します。どちらを使うかはファイルの存在確認だけで判断してください。メインエージェントでは、どちらの HTML ファイルも読み取ったり、grep、出力、クリーンアップ、解析したりしないでください。
分析スキルを使用してサブエージェントを実行します。サブエージェントへのプロンプトは /scrape-analyze-page で始める必要があり、サブエージェントはそのスキルを呼び出す必要があります。メインエージェントが代わりに clean_html.py、extract_metadata.py、sed、grep、cat、インラインの Python/lxml 解析を実行することは認められません。
Agent(description="analyze detail-1 rendered", prompt="/scrape-analyze-page Extract data from .scrape/.work/{site_name}/explore/pages/detail-1/rendered.html and save it into .scrape/.work/{site_name}/analyze-page/detail-1.rendered.json")
分析サブエージェントの実行を開始したら、完了するまで待ちます。想定される JSON ファイルが存在しない場合は、/scrape-analyze-page サブエージェントを再実行するか、ブロッカーを報告してください。HTML から自分で分析 JSON を作成してはいけません。
分析結果は .scrape/.work/{site_name}/analyze-page/detail-1.rendered.json から読み取ります。分析サブエージェントの実行後は、ダウンロードしたページの HTML やクリーンアップ済みの HTML を調べないでください。メインエージェントがフィールドを特定する際に使用できるのは、JSON の結果だけです。
ステップ 4:スキーマを作成する
分析結果から、JSON Schema を作成します。
- すべてのフィールド名と型を収集します
- 型を対応付けます:
str→string、float→number、int→integer、list→array、dict→object - 各フィールドに
descriptionを追加します(文脈から推測します) - field_hints に一致するフィールドには
"source": "requested"、それ以外には"source": "discovered"を設定します
ステップ 5:スキーマを簡易確認する
値を含むスキーマをターミナルに表示します。requested と discovered に分けてください。
Found {N} fields on {detail_page_url}:
Requested:
title (string): "A Light in the Attic"
price (string): "£51.77"
Discovered:
rating (integer): 3
category (string): "Poetry"
description (string): "It's hard to imagine a world without..." (2340 chars)
upc (string): "a897fe39b1053632"
image_url (string): "https://books.toscrape.com/media/cache/fe/72/..."
ユーザーの応答を待ちます。ユーザーは次の操作を行えます。
- 承認:「looks good」「ok」「approve」など → ステップ 6 に進みます
- フィールドを削除:「drop description, image_url」→ スキーマから削除し、更新後の内容を表示します
- discovered フィールドを保持:「keep rating」→ source を「requested」に変更します
- 名前を変更:「rename upc to product_code」→ スキーマ内の名前を変更します
- 説明を編集:「price should be without currency symbol」→ 説明と値を更新します
- その他の指示:適用し、更新後のスキーマを表示します
ユーザーが承認するまで、このやり取りを繰り返します。変更のたびにスキーマを再表示してください。
ステップ 6:仕様を保存する
データ型の仕様
.scrape/{site_name}/{data_type}/spec.json に書き込みます。出力は有効な JSON Schema(draft/2020-12)でなければなりません。以下に示す構造をそのまま使用してください。独自形式(フィールドオブジェクトの単純な配列など)を作成してはいけません。各スキーマフィールドに examples を含めてください。ユーザーが承認した値(修正がある場合は修正後の値)を使用します。これにより、ステージ 2 で想定される形式がわかります。すべてのフィールドに examples を含めてください。200 文字を超える値は「...」を付けて切り詰め、形式がわかるだけの内容を残してください。
{
"url": "https://books.toscrape.com",
"data_type": "product",
"html_variant": "rendered",
"schema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"title": {
"type": "string",
"description": "Book title as displayed on the detail page",
"source": "requested",
"examples": ["A Light in the Attic"]
},
"price": {
"type": "string",
"description": "Book price without currency symbol",
"source": "requested",
"examples": ["51.77"]
}
}
}
}
サイトレベルの仕様
.scrape/{site_name}/spec.json に書き込みます。
{
"url": "https://books.toscrape.com",
"data_types": ["{data_type}"]
}
注:data_types にはプライマリデータ型のみを記載します。/scrape-spec が後で「navigation」を追加します。
完了
Spec draft saved to .scrape/{site_name}/:
{data_type}: {N} fields
Run /scrape-spec .scrape/{site_name} to explore more pages and validate.