mcpField
S
scrape-codegen-analyze

scrape-codegen-analyze

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

关于 scrape-codegen-analyze

用于网页抓取分析的技能,可在保存的 HTML 中定位模式字段,并为独立的代码生成 Agent 编写提取说明。它会检查页面元数据与预期值,并区分列表页重复项和详情页字段。

主要功能

  1. 01分析已保存的 HTML 与元数据
  2. 02定位页面不同数据源中的字段
  3. 03识别列表页重复项选择器
  4. 04核对预期提取值
  5. 05将字段分析保存为 JSON

适用场景

  1. 01为详情页准备提取说明
  2. 02查找列表页重复项选择器
  3. 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:

  1. page_html_path:保存的 HTML 文件路径,例如 .scrape/spec/pages/detail-1/raw.html
  2. work_path:用于保存分析输出的工作目录,例如 .scrape/.work/spec
  3. spec_path:spec.json 文件路径,例如 .scrape/spec/spec.json
  4. 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): 页面包含多个重复的条目元素。不要只定位单个字段值,而应确定:

  1. 容器选择器 — 用于定位包裹每个条目的重复元素的 CSS 选择器(例如,article.product_pod、li.col-xs-6 article、div.item)。 找出包含所有请求字段的最小重复元素。 在分析输出中将其报告为 container_selector(参见步骤 4)。

  2. 相对于容器的各字段选择器 — 对每个字段,记录在单个容器元素内部有效的 CSS 选择器(例如,如果容器是 article.product_pod,那么相对于该容器,标题可能是 h3 a::attr(title))。 确认此相对选择器在页面上的多个容器实例中都能稳定生效。

  3. 预期条目数 — 记录找到的容器元素数量;该数量应与 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", ...

评论

支持 Markdown