mcpField
S
scrape-create-spider

scrape-create-spider

github.com/zytedataデータ・データベース11175 回インストール2 日前に更新
リポジトリ

scrape-create-spider について

scrape-create-spider は、web-poet のページオブジェクトを接続して Scrapy スパイダーを生成するスキルです。プロジェクトパス、抽出・ナビゲーション用ページオブジェクト、開始 URL に基づいて適切な形式を作成し、出力をテストします。

主な機能

  1. 01Scrapy スパイダーの生成
  2. 02ナビゲーションと抽出用ページの接続
  3. 03詳細ページ・一覧ページ形式に対応
  4. 04ドメインからスパイダー名を決定
  5. 05クロール実行とデータ確認

活用シーン

  1. 01既存の Scrapy プロジェクトにスパイダーを作成
  2. 02詳細ページからアイテムを抽出
  3. 03一覧ページから直接アイテムを抽出
  4. 04クロール結果のテストと問題調査

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/zytedata/skills --skill scrape-create-spider

インストール後、Claude Code で/scrape-create-spiderを入力して読み込まれたか確認します。

同梱ファイルreferences/scrapy-poet-reference.mdreferences/scrapy-zyte-api-reference.md

詳細

web-poet のページオブジェクト(アイテム抽出+ナビゲーション)を連携させ、動作するクローラーを生成します。

${CLAUDE_SKILL_DIR}/../scrape/references にある python-environments.md と docs-access.md を読みます。

入力

生の引数文字列は $ARGUMENTS です。これを空白区切りの位置引数 3 つに分割します。

  1. project_dir:Scrapy プロジェクトのパス
  2. item_page:アイテム抽出 PO のインポートパス(例:books_project.pages.books_toscrape_com.ProductPage)
  3. nav_page:ナビゲーション PO のインポートパス(例:books_project.pages.books_toscrape_com.NavigationPage)

さらに、周囲のプロンプトテキストから取得します(引数文字列からは取得しません)。

手順

1. プロジェクトと仕様を確認する

{project_dir} からプロジェクト名を特定します。

指定された PO のインポートパスを使用して、インポートするモジュール名とクラス名を特定します。 開始 URL を解析して、ドメインからスパイダー名を導出します。

スパイダーのパターンについては、references/scrapy-poet-reference.md を読みます。

リストページモードを検出する:item_page クラス名が ListPage で終わるか確認します(例:ProductListPage、BookListPage)。終わる場合はリスト抽出パターン(手順 2b)を使用します。それ以外の場合は詳細抽出パターン(手順 2a)を使用します。

2a. 詳細抽出スパイダーを生成する(デフォルト)

{project_name}/spiders/{spider_name}.py にスパイダーを書き込みます。

このスパイダーはナビゲーション PO でリンクを見つけ、アイテム抽出 PO で個々の詳細ページからデータを抽出します。パターン:

import scrapy
from scrapy_poet import DummyResponse

from {project_name}.pages.{module} import {ItemPage}, {NavPage}


class {SpiderClass}(scrapy.Spider):
    name = "{spider_name}"
    start_urls = ["{start_url}"]

    async def parse(self, response: DummyResponse, nav: {NavPage}):
        """Parse list/category pages — extract navigation links."""
        nav_item = await nav.to_item()

        # Follow item links → item extraction PO
        for link in nav_item.items or []:
            yield scrapy.Request(link["url"], callback=self.parse_item)

        # Follow pagination
        if nav_item.next_page:
            yield scrapy.Request(nav_item.next_page, callback=self.parse)

        # Follow subcategories
        for link in nav_item.subcategories or []:
            yield scrapy.Request(link["url"], callback=self.parse)

    async def parse_item(self, response: DummyResponse, page: {ItemPage}):
        """Extract item data."""
        yield await page.to_item()

主なポイント:

  • start_urls のデフォルトコールバックは parse です
  • コールバックの型注釈を使って PO を注入します
  • 生のレスポンスではなく PO だけが必要なため、response: DummyResponse を使用します
  • ページネーションとサブカテゴリのリンクは parse に再帰的に戻ります
2b. リスト抽出スパイダーを生成する(item_page が ListPage で終わる場合)

アイテムページ PO がリストページ抽出器(クラス名が ListPage で終わる)の場合、各リスト/カテゴリページから直接アイテムを抽出します。詳細ページへのリクエストは不要です。 ナビゲーション PO とリストページ PO の両方を同じ parse コールバックに注入します。

import scrapy
from scrapy_poet import DummyResponse

from {project_name}.pages.{module} import {ListPage}, {NavPage}


class {SpiderClass}(scrapy.Spider):
    name = "{spider_name}"
    start_urls = ["{start_url}"]

    async def parse(self, response: DummyResponse, nav: {NavPage}, list_page: {ListPage}):
        """Extract items from list page and follow navigation links."""
        nav_data = await nav.to_item()
        list_data = await list_page.to_item()

        for item in list_data.items or []:
            yield item

        if nav_data.next_page:
            yield scrapy.Request(nav_data.next_page, callback=self.parse)

        for sub in nav_data.subcategories or []:
            yield scrapy.Request(sub["url"], callback=self.parse)

主なポイント:

  • NavPage と ListPage はどちらも型注釈を使って parse に注入します
  • アイテムは list_data.items から直接取得し、parse_item コールバックは使用しません
  • list_page はリストページ PO の注入に使うパラメーター名です
  • ページネーションとサブカテゴリのリンクは parse に再帰的に戻ります
3. 命名
  • spider_name:ドメインから導出します(例:books_toscrape_com)
  • SpiderClass:PascalCase 形式(例:BooksToscrapeCom)
  • module:ページオブジェクトのモジュールファイル(同じドメインベースの名前)
4. カスタム設定(必要な場合)

サイトで Zyte API が必要な場合(例:仕様の構築中に検出された場合)、次を追加します。

    custom_settings = {
        "ZYTE_API_TRANSPARENT_MODE": True,
    }

scrapy-zyte-api のリファレンスを読みます。

references/scrapy-zyte-api-reference.md
5. スパイダーをテストし、アイテムを検証する

アイテムをファイルに保存するテストクロールを実行し、内容を確認できるようにします。

cd {project_dir} && uv run scrapy crawl {spider_name} -s CLOSESPIDER_ITEMCOUNT=5 -o items.jsonl 2>&1

クロールに失敗した場合(終了コードが 0 以外、または出力に例外がある場合):

  • エラーメッセージを確認します
  • ページオブジェクトのインポートが正しいことを確認します
  • SCRAPY_POET_DISCOVER に pages モジュールが含まれていることを確認します
  • Zyte API を使用している場合は、ZYTE_API_LOG_REQUESTS=True を指定して試します

クロールが成功したら、items.jsonl を読み、データ品質に明らかな問題がないか確認します。問題が見つかった場合は、関連するページオブジェクトを読み、根本原因を診断して修正し、items.jsonl を削除して再実行します。さらに最大 2 回(合計 3 回)繰り返します。3 回試してもアイテムに問題がある場合は、そこで停止し、確認した内容を報告します。

アイテムが正しいと確認できてから、スパイダーの完成を宣言します。

6. 報告

詳細抽出スパイダーの場合:

Created spider at {project_name}/spiders/{spider_name}.py:
  Start URL: {start_url}
  Navigation: {NavPage} → follows items, pagination, subcategories
  Extraction: {ItemPage} → parse_item callback

Run: cd {project_dir} && uv run scrapy crawl {spider_name}

リスト抽出スパイダーの場合:

Created spider at {project_name}/spiders/{spider_name}.py:
  Start URL: {start_url}
  Navigation: {NavPage} → follows pagination and subcategories
  Extraction: {ListPage} → items extracted directly from list pages

Run: cd {project_dir} && uv run scrapy crawl {spider_name}

コメント