关于 scrape
该技能引导 Agent 从规划到构建带有 web-poet 页面对象和夹具的 Scrapy 爬虫,适用于需要结构化计划及测试的网页抓取任务,也涵盖复用现有项目。
主要功能
- 01提取目标 URL 与所需数据
- 02检测并复用 Scrapy 项目
- 03调用 /scrape-plan 进行规划
- 04构建 web-poet 页面对象和夹具
- 05运行夹具测试与有界爬取
适用场景
- 01向现有 Scrapy 项目添加爬虫
- 02抓取网站的商品或列表数据
- 03使用已捕获页面和夹具验证提取结果
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ zytedata/ skills --skill scrape安装后在 Claude Code 中输入/scrape确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
meta.jsonreferences/docs-access.mdextraction-spec.mdpython-environments.mdscripts/detect_projects.pyfeedback_state.py详细介绍
此文件共 296 行;请完整阅读。
下文中的 SKILL_DIR 表示包含此文件的目录的绝对路径。SKILLS_DIR 表示存放所有技能目录的目录,其中一个就是 SKILL_DIR。
你负责协调完整的网页抓取工作流,从用户提示词到可运行的 Scrapy 蜘蛛和 web-poet 页面对象。
前提条件
需要 uv。如果尚未安装,请安装。
输入
这是用户提示词:$ARGUMENTS。你需要从中提取以下信息:
- url:目标网站 URL。可以是主页,也可以是某个具体详情页。
- what:要提取的内容(例如“产品”“职位列表”“食谱”)
- 其他有用的细节:会影响计划的用户指示 (例如,要提取哪些字段、是否使用浏览器渲染等)
项目上下文
此工作流可能在已有 Scrapy 项目的代码库中运行。 重复运行时,通常应向现有项目添加蜘蛛,而不是另建一个以域名命名的项目。
候选项目是当前目录或其直接子目录中包含 scrapy.cfg 的目录。items.py、spiders/、pages/ 和独立的 pyproject.toml 都不能作为项目标记。忽略 .venv、.scrape、__pycache__ 和其他生成目录。
随附脚本会应用这些标准,并以 JSON 格式输出每个候选项及其 project_dir。请在移交架构之前运行,以便 /scrape-plan 能参考项目和架构上下文:
uv run SKILL_DIR/scripts/detect_projects.py
如果没有候选项目,请使用基于域名的命名方式创建新项目。如果有多个候选项目,请询问要使用哪一个,或是否创建新项目——不要自行猜测。
如果恰好有一个候选项目,则根据用户的措辞决定:
- 要求复用或扩展现有项目 → 选中该项目。
- 要求使用现有架构 → 选中存放该架构的项目,然后对其 item 类应用下方的架构匹配规则。
- 要求添加蜘蛛,且未要求创建新项目 → 视为希望复用。“为 https://example.com 添加一个蜘蛛”表示扩展现有的那个项目。
- 明确要求创建新项目 → 创建新项目,跳过复用。
- 其他较宽泛的要求(“创建一个抓取器”“抓取此网站”)→ 需要先询问:复用该项目还是单独创建一个项目,因为架构定义取决于此决定。
选定项目后,无需确认;在简短的状态说明中注明项目名称。
复用项目时,记录:
project_dir:包含scrapy.cfg的项目根目录project_name:scrapy.cfg中默认设置模块对应的 Python 包(例如,catalog_crawlers.settings表示catalog_crawlers包)
选定项目后,读取其 scrapy.cfg 以确定包名,并检查项目结构。
定义架构之前,如果 {project_name}/items.py 存在,请读取该文件并列出已有的 item 类和字段。
还要查找现有的 .scrape/*/*/spec.json 文件,作为先前架构的上下文。将现有 items.py 视为生成代码的真实来源;.scrape 规格文件可作为有用的上下文和示例。利用这些上下文,避免要求用户重新定义未变化的字段,并防止意外破坏现有 item、页面对象、测试数据或蜘蛛。
只有当现有架构与用户想要提取的内容合理匹配时,才选择该架构。将用户请求的单数数据类型与 item 类名进行匹配,忽略仅用于导航的类,以及唯一字段为 item 列表的列表包装类。如果用户明确要求复用现有架构,且恰好有一个类合理匹配,则使用该类。如果有多个类合理匹配,请询问用户要复用哪一个。如果没有匹配项,则复用项目,但按常规定义新的数据类型;不得将无关 item 类的字段带入新架构。
工作流
只要某一阶段已满足用户的请求,就在该阶段结束,例如计划获批后。
每个阶段的结果都会传递给下一阶段:经过验证的计划会传入构建阶段。对于常规的端到端请求,请运行两个阶段、有限的测试爬取,以及最终报告。如果用户明确要求仅执行部分工作流或在某个阶段停止,存在尚未解决的项目/架构决策,或发生不可恢复的错误而无法继续,则已获批的架构、完成的规范、准备好的项目等中间结果也可作为有效的工作流输出。
不要因为网站看起来简单,或用户在请求中明确列出了字段,就跳过此工作流。请求“添加爬虫”“创建抓取器”或“创建并测试抓取器”均属于端到端请求:先使用 /scrape-plan 运行阶段 1,再运行阶段 2。不要在父工作流中直接检查目标网站的 HTML,以替代计划或网站分析。
阶段 1:规划并验证
使用 /scrape-plan 技能规划抓取并生成经过验证的规范。调用时,提供从用户提示中提取的所有信息。如果复用现有项目,请在提示中简要说明现有的项目项类/字段以及任何相关的现有规范,以便架构发现从项目上下文开始,而不是把项目当作空文件夹。
此阶段必须实际移交给 /scrape-plan。明确调用 scrape-plan 技能,并等待它创建 .scrape/{site_name}/。在 /scrape-plan 运行之前,不要在父工作流中手动创建 .scrape/{site_name}/spec.json 或数据类型规范文件来代替规划。整个执行过程应清楚表明:在生成网站专属规范文件之前,已将所选项目上下文和任何现有的获批架构传递给 /scrape-plan。
如果选择了现有项类作为架构:
- 将其确切字段名和表面类型作为请求字段传递给
/scrape-plan,并附上匹配的先前规范中有用的描述/示例。说明这些现有字段属于获批架构。使用明确的移交语句,例如Existing approved schema: ProductItem(title: string, price: string, rating: string),并告知/scrape-plan原样复用这些字段,对未更改的字段跳过用户审批。不要再次要求用户列出或审批未更改的字段。 /scrape-plan仍须分析新网站以获取代表性值和提取证据,但不得擅自添加无关的已发现字段或删除现有字段。如果无法找到某个现有字段,或其类型看起来不兼容,则应报告该冲突,并在更改架构前征求确认。
如果没有匹配的现有项类,请使用常规的发现和审批流程。
用户在请求中指定的字段也属于获批架构:将这些字段作为已获批内容交给 /scrape-plan,不要询问用户要保留哪些已发现字段或如何格式化值。
/scrape-plan 会确认架构,然后下载并分析更多页面、比较 HTML 变体、提取值,并可选择展示浏览器审查;最后会展示最终计划供审批。它会返回一份包含后续阶段所需全部详情的最终计划。示例:
Plan approved. Spec validated and saved to .scrape/books-toscrape/.
Details:
- Data types: product, navigation
- Project dir: ./books_toscrape_com
- Project name: books_toscrape_com
- Create the spider: yes
- Start URLs: https://books.toscrape.com
- Using Zyte API: no
解析这些值;后续阶段会用到它们。
阶段 2:构建可用项目
这是编码阶段:阅读 /scrapy-extra,了解当前 Scrapy/web-poet 约定、项目模板和测试循环——它是本项工作的知识库,不是要移交规范的步骤。遵循其中的要求,将 {spec_path} 处的规范转化为可用且经过测试的爬虫。/scrapy-extra 未涵盖的规范专属输入:
不要用纯选择器 Scrapy 爬虫来替代此阶段。此工作流的输出应是由 web-poet 页面对象支持的 Scrapy 爬虫,以及根据已捕获的规范页面生成的 web-poet fixtures。
-
全新运行:在
{project_dir}中创建新的 Scrapy 项目(包名为{project_name}),这两个值均由/scrape-plan报告。复用项目:在现有的{project_dir}和{project_name}包中工作——不创建新的 项目目录。 -
规范中每种由
/scrape-plan报告的数据类型各有一个文件夹(例如product、navigation),每个文件夹都包含spec.json(架构、html_variant、url)、保存在pages/下的页面,以及保存在values/下的预期值。对于 每种数据类型,添加一个条目类和一个 web-poet 页面对象,其@field方法需在所有保存的页面中生成与预期值一致的结果。 -
主要数据类型是第一个非
navigation的类型;navigation始终存在。当主要 类型以-list结尾(例如product-list)时,所有请求的字段都在列表页面上 找到:其页面对象从列表页面提取条目列表,爬虫直接在parse()中生成这些条目, 不使用详情页回调。否则,网站采用详情页提取方式(默认方式)。 -
在复用项目中,除非用户批准更改,否则现有条目类、页面对象、测试样例和 爬虫都应保持不变。与数据类型匹配的现有条目类就是要使用的类——为其添加缺失的 架构字段,并设为可选字段,而不是创建重复类(预先存在的
ProductItem应继续使用ProductItem)。仅根据新的目标域名推导新爬虫和模块的名称; 导入路径仍应位于现有{project_name}包下。若与现有爬虫发生名称或文件冲突, 应使用由域名或数据类型推导出的独立名称,而不是替换现有爬虫。按照现有项目的 条目、页面对象、测试样例和爬虫惯例,尽可能少量地添加内容;复用不代表可以 重构无关的项目代码。 -
使用规范中已捕获的页面构建 web-poet 测试样例——不要用
savefixture重新获取页面(这会重新下载每个页面,并记录可能与页面对象所依据的 HTML 不一致的新 HTML)。而是,在每个页面对象就绪后,针对每种数据类型运行打包的 辅助脚本,并传入页面对象的导入路径(从此技能目录解析SCRIPT):SCRIPT=SKILLS_DIR/scrape-plan/scripts/make_fixtures.py uv run --python 3.14 "$SCRIPT" {spec_path}/{data_type} {project_dir} {PageObjectImportPath}该脚本会复用已保存的 HTML,并根据规范中的
values/设置每个output.json, 因此无需网络往返即可通过测试样例。 -
编写一个爬虫,使用导航页面对象跟进条目链接、分页和子类别,并使用条目页面对象 提取每个条目。使用
/scrape-plan报告的起始 URL。html_variant为rendered的数据类型需要浏览器渲染。
如果计划要求不要创建爬虫,则跳过爬虫;页面对象及其测试样例就绪后即可完成。
报告成功前,请确认已使用上述辅助脚本生成测试样例,并且测试通过
(uv run --with pytest python -m pytest fixtures/)。除非跳过了爬虫,
还需确认已运行有界测试爬取并检查了其条目——在复用项目中,只测试新爬虫的爬取;
不要重新测试或修改现有爬虫。使用 CLOSESPIDER_ITEMCOUNT 或
CLOSESPIDER_PAGECOUNT 限定爬取范围;不要仅为验证爬虫而运行无界的全站爬取。
将临时爬取输出文件保存在工作区内,例如 .scrape/.work/{site_name}/,以便
沙箱化的测试工具无需权限提示即可创建这些文件;避免使用 /tmp、
/private/tmp 等外部输出路径。最终报告中至少逐字提供一个抓取到的条目,
让用户看到实际提取的字段值,而不只是数量。
反馈标记
以下每个最终的第 3 阶段结果,都应在汇报前、仍在执行命令时,立即记录一次性反馈标记;这是工作流的最终结果信号,用于可选的会话结束反馈提示,不会直接提示用户。用户中止的工作流或爬取前的设置阻碍(例如缺少凭据)不应记录此标记——会话停止钩子会处理冷却时间和提示。
如果有限范围的爬取或必需的夹具测试在你尝试修复后仍然失败,请停止,汇报你发现的情况,并记录标记:
SCRAPE_FEEDBACK_STATE_FILE=".scrape/.work/feedback/state.json" \
SCRAPE_FEEDBACK_MARKER_FILE=".scrape/.work/feedback/marker.json" \
SCRAPE_FEEDBACK_EVENT_LOG_FILE=".scrape/.work/feedback/events.jsonl" \
uv run --no-project "SKILL_DIR/scripts/feedback_state.py" mark --context scrape_failed
如果爬取成功,但你尝试修复后,条目看起来仍有错误或不完整,请停止,汇报你发现的情况,并记录标记:
SCRAPE_FEEDBACK_STATE_FILE=".scrape/.work/feedback/state.json" \
SCRAPE_FEEDBACK_MARKER_FILE=".scrape/.work/feedback/marker.json" \
SCRAPE_FEEDBACK_EVENT_LOG_FILE=".scrape/.work/feedback/events.jsonl" \
uv run --no-project "SKILL_DIR/scripts/feedback_state.py" mark --context scrape_incomplete
只有在夹具测试通过、有限范围的爬取运行成功且检查过的条目看起来正确后,才能宣布工作流完成。满足这些条件后,记录标记:
SCRAPE_FEEDBACK_STATE_FILE=".scrape/.work/feedback/state.json" \
SCRAPE_FEEDBACK_MARKER_FILE=".scrape/.work/feedback/marker.json" \
SCRAPE_FEEDBACK_EVENT_LOG_FILE=".scrape/.work/feedback/events.jsonl" \
uv run --no-project "SKILL_DIR/scripts/feedback_state.py" mark --context scrape_success
报告
Created scraping solution for {domain}:
Project: {project_dir}/
Spider: uv run scrapy crawl {spider_name}
Tests: uv run --with pytest python -m pytest fixtures/
如果跳过了 Spider 创建步骤,请省略 Spider 行。
如果用户有意愿,请主动提出帮助其部署到 Scrapy Cloud。它适用于定时或长时间运行的爬取,可保留包含结果和日志的任务历史、监控任务(提供可供大模型使用的 API)等。此外,还有一个免费套餐。
部署通过 /zyte 进行;在此运行 Spider,以及监控和验证其任务,则需使用 Zyte MCP 的 Scrapy Cloud 工具。