scrape-codegen について
抽出仕様と保存済み HTML をもとに、Scrapy プロジェクト向けの web-poet ページオブジェクトを生成し、テストする Claude スキルです。
主な機能
- 01ページオブジェクトの雛形生成
- 02保存済み HTML ページの分析
- 03スキーマに基づく抽出コード生成
- 04フィクスチャ変換とテスト実行
活用シーン
- 01抽出仕様からページオブジェクトを作成
- 02リストページの抽出コードを生成
- 03保存済みフィクスチャで抽出をテスト
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ zytedata/ skills --skill scrape-codegenインストール後、Claude Code で/scrape-codegenを入力して読み込まれたか確認します。
同梱ファイルscripts/convert_fixtures.py
詳細
抽出仕様から web-poet ページオブジェクトを生成します。仕様には、スキーマ、保存済みの HTML ページ、期待される値が含まれています。商品詳細、ナビゲーションリンク、記事の内容など、どのようなデータ型も記述できます。Codegen はデータ型を把握する必要はありません。スキーマに従って抽出する PO を生成します。
仕様は /scrape-spec によって作成され、プロジェクトは /scrape-ensure-project によって作成されています。
${CLAUDE_SKILL_DIR}/../scrape/references から python-environments.md と docs-access.md を読みます。
入力
生の引数文字列は $ARGUMENTS です。空白で区切られた位置引数を最大 3 つに分割します。
- spec_path:仕様フォルダーのパス。例:
.scrape/books-toscrape - project_dir:Scrapy プロジェクトのパス
- fields:任意。生成するフィールド名をカンマ区切りで指定します(空の場合はすべてのフィールド)
処理
ステップ 1:仕様を読み取る
{spec_path}/spec.json を読み取り、以下を取得します。
schema.properties— フィールド定義html_variant— 使用する HTML(rawまたはrendered)url— 開始 URL(ドメイン名に使用)data_type— 抽出対象(クラス名に使用)。常に単数形です(例:product、book)
次の規則に従って data_type から名前を導出します(複数形にはしません)。
ClassName= PascalCase +Page→product→ProductPageItemClass= PascalCase +Item→product→ProductItemmodule_name=data_typeの snake_case →product→product
fields が指定されている場合は、schema.properties をそのフィールドのみに絞り込みます。
{spec_path}/pages/ 内のページディレクトリのうち、{spec_path}/values/ に対応する値があるものを一覧表示します。それぞれの期待値を読み取ります。
spec_path から site_name を導出します(親ディレクトリ名。例:.scrape/books-toscrape/products から books-toscrape)。{project_dir} からプロジェクト名を特定します。
リスト型の判定。 data_type が -list で終わる場合(例:products-list):
is_list_type = trueに設定します。-listの接尾辞を取り除いてbase_typeを設定します(例:products)。base_typeの末尾にsがある場合は削除して単数形にし、その後 TitleCase にしてItemClassを導出します(例:products→product)。すでに単数形に見える場合は、そのまま TitleCase にします。WrapperClass = {ItemClass}ListItems(例:ProductListItems)PageClass = {ItemClass}ListPage(例:ProductListPage)- 値は配列形式です:
{"url": ..., "values": [{...}, ...]}
それ以外の場合は is_list_type = false に設定し、ClassName を TitleCase(data_type) + "Page" として導出します。
ステップ 2:アイテムとページオブジェクトのスタブを追加する
リスト型でない場合(is_list_type = false):
{project_name}/items.py に data_type に一致する既存のアイテムクラスがあるか確認します。存在しない場合は、スキーマに基づいて作成します(すべてのフィールドは省略可能で、| None = None とします)。
親スキルが後続の処理を続けられるよう、サブエージェントでページオブジェクトのスタブを追加します。
Agent(description="add page object stub", prompt="/scrape-add-page-object {project_dir}/{project_name}/pages/{module_name}.py {ClassName} {domain} web_poet.WebPage {project_name}.items.{ItemClass}")
html_variant が rendered の場合は、web_poet.BrowserPage を使用します。
リスト型の場合(is_list_type = true):
items.py に 2 つのクラスが必要です。存在するか確認し、不足しているクラスを作成します。
-
ベースアイテムクラス(
ItemClass。例:Product)— フィールドの型をスキーマに合わせた@dataclassです。例:@dataclass class Product: title: str price: str | None = None -
ラッパークラス(
WrapperClass。例:ProductListItems)—itemsフィールドを 1 つだけ持ち、その型はlist[ItemClass] | None = Noneの@dataclassです。例:@dataclass class ProductListItems: items: list[Product] | None = None
次に、サブエージェントでページオブジェクトのスタブを追加します。デフォルト値を持つラッパーフィールドだけの場合でも @field スタブが生成されるよう、items を引数 6 として明示的に渡します。
Agent(description="add page object stub", prompt="/scrape-add-page-object {project_dir}/{project_name}/pages/{module_name}.py {PageClass} {domain} web_poet.WebPage {project_name}.items.{WrapperClass} items")
ステップ 3:フィクスチャを変換する
プロジェクト構造からフィクスチャクラスのパスを特定します(例:
{project_name}.pages.{module_name}.{ClassName})。
uv run ${CLAUDE_SKILL_DIR}/scripts/convert_fixtures.py \
{spec_path} {project_dir} {fixture_class_path}
ステップ 4:ページを分析する(並列実行)
mkdir -p .scrape/.work/{site_name}/codegen-analyze
値を指定して、ページごとに 1 つの Agent を起動し、並列実行できるようすべてを 1 つのメッセージにまとめます。各エージェントは、4 つすべての引数を指定して /scrape-codegen-analyze を実行します。
/scrape-codegen-analyze {spec_path}/pages/{page_id}/{html_variant}.html .scrape/.work/{site_name} {spec_path}/spec.json {spec_path}/values/{page_id}.json
HTML ファイルが存在しないページはスキップします。
リスト形式の仕様では、ページ名は list-* で、値には配列が含まれます。
scrape-codegen-analyze スキルは、meta.json(page_type が list)からリストページを自動検出し、コンテナーをベースとした抽出手順を生成します。
ステップ 5:ページオブジェクトのコードを生成する
すべての分析エージェントの完了後、3 つすべての引数を指定して /scrape-codegen-generate を実行する Agent を 1 つ起動します。
/scrape-codegen-generate .scrape/.work/{site_name} {project_dir}/{project_name}/pages/{module_name}.py {spec_path}/spec.json
ステップ 6:テストする
cd {project_dir} && uv run pytest fixtures/ -x -v
結果を報告します。テストに失敗した場合は、エラーを確認し、失敗したフィールドの再生成を検討します。
ステップ 7:報告する
Generated page object at {project_dir}/{project_name}/pages/{module_name}.py:
Class: {ClassName} (N fields)
Fixtures: N test cases
Tests: N/N passing
コード生成のルール
${CLAUDE_SKILL_DIR}/../scrape/references/web-poet.md の web-poet リファレンスに従い、さらに以下を守ります。
- コードはシンプルでドメイン汎用的なものにし、サンプルページに過剰適合させないでください
- データがない場合は
Noneを返します。空文字列、False、[]は決して返さないでください - ガード節を使い、属性にアクセスする前に
Noneかどうかを確認してください - フィールドメソッドに docstring を追加しないでください
- 汎用的な
Exceptionを捕捉せず、具体的な例外のみを捕捉してください - 決定的な出力を優先し、セットは避けてください(必要に応じて、リストと重複排除を使用します)
- 分析でフィールドの取得元が構造化データ(JSON-LD、microdata)と判明した場合は、
extructを使用してください。メタデータ形式は前の段階のextract_metadata.pyの出力と一致するため、ページオブジェクトでも同じアクセスパターンを利用できます - ブラウザーのレスポンスが必要な場合は、基底クラスとして
BrowserPageを使用してください