关于 scrape-codegen-analyze
用于网页抓取分析的技能,可在保存的 HTML 中定位模式字段,并为独立的代码生成 Agent 编写提取说明。它会检查页面元数据与预期值,并区分列表页重复项和详情页字段。
主要功能
- 01分析已保存的 HTML 与元数据
- 02定位页面不同数据源中的字段
- 03识别列表页重复项选择器
- 04核对预期提取值
- 05将字段分析保存为 JSON
适用场景
- 01为详情页准备提取说明
- 02查找列表页重复项选择器
- 03将预期值与页面内容核对
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ zytedata/ skills --skill scrape-codegen-analyze安装后在 Claude Code 中输入/scrape-codegen-analyze确认已加载。
详细介绍
You are analyzing a detail page to produce extraction instructions for a code generation system. Given an HTML page, a schema, and expected values, you determine WHERE and HOW each field can be extracted from the page.
Read ${CLAUDE_SKILL_DIR}/../scrape/references/python-environments.md.
Your analysis will be read by a separate code-generation agent that does not have access to the HTML. It must be detailed enough for that agent to write correct web-poet extraction code.
Input
The raw argument string is $ARGUMENTS. Split it into 4 whitespace-separated positional arguments:
- page_html_path:保存的 HTML 文件路径,例如
.scrape/spec/pages/detail-1/raw.html - work_path:用于保存分析输出的工作目录,例如
.scrape/.work/spec - spec_path:spec.json 文件路径,例如
.scrape/spec/spec.json - values_path:此页面的 values JSON 文件路径,例如
.scrape/spec/values/detail-1.json
此外,从周围的提示文本中获取(而非从参数字符串中获取):
- fields:可选的、需要分析的特定字段(在提示中以“Only analyze these fields: ...”的形式提供)。设置后,只分析 schema 中指定的字段,跳过其余字段。未设置时,分析所有字段。
页面目录(HTML 文件的父目录)还包含带有源 URL 的 meta.json。
Process
1. Read inputs and prepare HTML
从目录名称中推导 page_id(例如,从 .../detail-1/raw.html 中得到 detail-1)。
从同一目录读取 meta.json,获取源 URL 和 page_type。
如果 meta.json 中 "page_type": "list",或者 page_id 以 list- 开头,则设置 is_list_page = true。这会改变字段的分析方式(见步骤 2)。
从 {spec_path} 读取 schema——使用其中的 properties 对象。
从 {values_path} 读取预期值——使用其中的 values 对象(可能为 {})。
清理 HTML 并提取结构化元数据。使用 0 级清理以保留脚本(脚本中可能包含 JSON-LD/嵌入式数据):
mkdir -p {work_path}/codegen-analyze
uv run ${CLAUDE_SKILL_DIR}/../scrape-analyze-page/scripts/clean_html.py PAGE.html -l0 -o {work_path}/codegen-analyze/{page_id}.cleaned.html
uv run ${CLAUDE_SKILL_DIR}/../scrape-analyze-page/scripts/extract_metadata.py PAGE.html -u PAGE_URL -o {work_path}/codegen-analyze/{page_id}.metadata.json
仅读取清理后的 HTML(而非原始 HTML)和元数据 JSON。
2. 分析每个字段
对于列表页(is_list_page = true): 页面包含多个重复的条目元素。不要只定位单个字段值,而应确定:
-
容器选择器 — 用于定位包裹每个条目的重复元素的 CSS 选择器(例如,
article.product_pod、li.col-xs-6 article、div.item)。 找出包含所有请求字段的最小重复元素。 在分析输出中将其报告为container_selector(参见步骤 4)。 -
相对于容器的各字段选择器 — 对每个字段,记录在单个容器元素内部有效的 CSS 选择器(例如,如果容器是
article.product_pod,那么相对于该容器,标题可能是h3 a::attr(title))。 确认此相对选择器在页面上的多个容器实例中都能稳定生效。 -
预期条目数 — 记录找到的容器元素数量;该数量应与 values 数组中的条目数一致。
列表页的分析应描述基于容器的提取模式,以便 scrape-codegen-generate 能生成 for container in self.css(...): 循环。
对于详情页: 针对架构中的每个字段,进行详细分析。 考虑 HTML 中所有可能的数据来源:
- HTML 元素:标签、类、ID、属性 — 记录 CSS 选择器或 XPath
- JSON-LD:
<script type="application/ld+json">块 — 记录 JSON 路径 - 微数据:
itemscope/itemprop属性 - OpenGraph:
<meta property="og:...">标签 - 其他脚本标签:
<script>标签中的嵌入式 JSON(例如,window.__DATA__ = {...}) - URL 组件:可从页面 URL 推导出的数据
- Meta 标签:
<meta name="...">标签 - 隐藏输入项或
data-*属性
对找到的每种来源,描述:
- 可定位到数据元素的 CSS 选择器或 XPath
- 所需的后处理(文本提取、正则表达式、JSON 路径、类型转换)
- 可靠性:选择器是否唯一且稳定,还是容易失效?
- 显示相关元素上下文的简短 HTML 片段(使用
...缩短过长内容)
然后推荐最佳提取方法并说明原因。
3. 确定目标值
针对每个字段,确定正确的目标提取值:
- 如果提供了预期值,请对照 HTML 中的实际内容进行核验
- 如果一致,则使用这些值
- 如果看起来有误或不完整,请指出差异,并根据 HTML 提供更正后的值
- 如果此页面中没有某字段的数据,则设为
null
4. 保存分析结果
保存到 {work_path}/codegen-analyze/{page_id}.json。
对于详情页:
{
"url": "https://example.com/product/widget-x",
"page_id": "detail-1",
"fields": {
"name": {
"target_value": "Widget X",
"analysis": "The product name appears in two places:\n\n1. **HTML element** `<h1 class=\"product-title\">Widget X</h1>`\n - Selector: `h1.product-title::text`\n - Clean text, no post-processing needed\n - Reliable: unique h1 on the page\n\n2. **JSON-LD** in `<script type=\"application/ld+json\">`:\n ```json\n {\"@type\": \"Product\", \"name\": \"Widget X\", ...}\n ```\n - Path: `name` on the Product object\n - Also reliable\n\nRecommended: CSS selector `h1.product-title::text` — simplest, most direct."
},
"price": {
"target_value": "$29.99",
"analysis": "..."
}
}
}
对于列表页,请包含 container_selector 和 item_count,并在各字段分析中使用容器内的相对选择器:
{
"url": "https://example.com/category/widgets/",
"page_id": "list-1",
"is_list_page": true,
"container_selector": "article.product_pod",
"item_count": 20,
"fields": {
"name": {
"target_values": ["Widget X", "Widget Y", "..."],
"analysis": "Container: article.product_pod\nRelative selector: h3 a::attr(title)\nFinds the full product title in the anchor's title attribute.\nVerified across 20 containers on the page."
},
"price": {
"target_values": ["$29.99", "$14.99", "..."],
"analysis": "Container: article.product_pod\nRelative selector: p.price_color::text\nFinds the price text directly. Verified across 20 containers."
}
}
}
5. 返回摘要
对于详情页,返回简洁摘要:
detail-1 (https://...):
name: "Widget X" — h1.product-title, also in JSON-LD
price: "$29.99" — span.price::text, JSON-LD offers.price
description: "A premium widget..." (2340 chars) — div.description
rating: null — not found in HTML
对于列表页,请包含容器选择器和条目数:
list-1 (https://...): 20 items, container: article.product_pod
name: h3 a::attr(title) — "Widget X", "Widget Y", ...
price: p.price_color::text — "$29.99", "$14.99", ...