mcpField
S
scrape-create-spider

scrape-create-spider

github.com/zytedata数据与数据库11175 次安装2 天前更新
代码仓库

关于 scrape-create-spider

scrape-create-spider 是用于生成 Scrapy 爬虫的技能,将 web-poet 页面对象连接为可运行的采集器。它根据输入的项目路径、提取与导航页面对象以及起始 URL,生成对应模式的爬虫并测试结果。

主要功能

  1. 01生成 Scrapy 爬虫
  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

详细介绍

你正在生成一个 Scrapy Spider,将 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,根据域名生成 Spider 名称。

阅读 references/scrapy-poet-reference.md,了解 Spider 模式。

检测列表页模式:检查 item_page 类名是否以 ListPage 结尾 (例如 ProductListPage、BookListPage)。如果是,使用列表提取模式(步骤 2b);否则使用详情提取模式(步骤 2a)。

2a. 生成详情提取 Spider(默认)

将 Spider 写入 {project_name}/spiders/{spider_name}.py。

该 Spider 使用导航 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()

要点:

  • parse 是 start_urls 的默认回调
  • 通过回调上的类型注解注入 PO
  • 使用 response: DummyResponse,因为我们只需要 PO,不需要原始响应
  • 分页和子类别链接会递归返回 parse
2b. 生成列表提取 Spider(当 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. 测试 Spider 并验证条目

运行测试爬取,将条目保存到文件中以便检查:

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

如果爬取失败(退出码非零、输出中有异常):

  • 检查错误消息
  • 确认页面对象导入路径正确
  • 确认 SCRAPY_POET_DISCOVER 包含 pages 模块
  • 如果使用 Zyte API,尝试设置 ZYTE_API_LOG_REQUESTS=True

如果爬取成功,读取 items.jsonl 并检查是否存在明显的数据质量问题。如果发现问题,读取相关页面对象,诊断并修复根本原因,删除 items.jsonl,然后重新运行。最多再重复 2 次(总计 3 次)。如果尝试 3 次后条目看起来仍不正确,请停止并报告发现的问题。

只有在条目看起来正确后,才能宣布 Spider 已完成。

6. 报告

对于详情提取 Spider:

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}

对于列表提取 Spider:

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}

评论

支持 Markdown