Back to skills
extension
Category: Data & AnalyticsNo API key required

中国统计年鉴官网-数据抓取技能

This skill should be used when downloading and structuring data from China Statistical Yearbook (中国统计年鉴) on stats.gov.cn. It covers locating chapter tables, batch downloading table images, recognizing tables via multimodal LLM (no traditional OCR), and generating Excel files. **Requires a multimodal LLM** (such as Hy3, MinMax, Kimi, GLM-5V) to perform OCR on the downloaded JPG tables. Includes worked table indexes for chapter 21 (Education) and chapter 2 (Population) as reference examples. Triggers: 抓取中国统计年鉴数据、下载年鉴表格、年鉴数据转Excel、统计年鉴图片识别、stats.gov.cn 表格下载、人口数据、教育数据.

personAuthor: user_2761353ahubcommunity

China Statistical Yearbook Crawler

[!WARNING]

⚠️ 使用前提:必须使用支持「多模态」的大模型

本技能的核心步骤是对国家统计局年鉴的 JPG 图片进行视觉 OCR 识别在开始任何下载或识别之前,请务必确认当前正在使用支持「多模态」的大模型,例如:

  • Hy3
  • MinMax
  • Kimi
  • GLM-5V

若当前为纯文本大模型,Read 工具将无法读取图片内容,本技能将无法有效工作——继续运行只会下载一堆图,却识别不出任何数据。

如果你(AI)不确定当前模型是否支持多模态,请执行 Step 0 自检(10 秒即可)。 不要盲目进入 Step 1,否则可能下载完一整章(数张至二十余张)图片才发现完全无法 OCR。

Step 0: 多模态自检(开工前必做,约 10 秒)

目的:在下载任何年鉴数据之前,自动判定当前模型是否支持多模态图像识别。非多模态环境下继续只会浪费网络和时间。

做法

  1. Read 工具读取本技能自带的自检图 assets/multimodal_selfcheck.png(120x40 像素,红/绿/蓝三色块,188 字节)。
  2. 根据返回值判定:

| 返回特征 | 判定 | 下一步 | |----------|------|--------| | 看到红/绿/蓝三色块的视觉内容(任意形式描述,如"三色块""RGB""色带"等) | ✅ 多模态 OK | 输出 [OK] 多模态自检通过,进入 Step 1 | | 返回 [Image from ...] 标记 + 图像描述 | ✅ 多模态 OK | 同上 | | 出现 synthetic_tool_result: true / synthetic placeholder | ⚠️ 重试一次 | 重试成功 → OK;仍失败 → 不可用 | | 返回 Content filtered / model does not support images / 系统提示当前模型不支持图像 | ❌ 非多模态 | 立即停止,向用户明示:「⚠️ 当前模型不支持图像识别,本技能无法继续。请切换到支持「多模态」的大模型(如 Hy3、MinMax、Kimi、GLM-5V 等)后重试。」不要进入 Step 1 | | Read 工具调用直接报错/异常 | ❌ 不可用 | 同上处理 |

  1. 自检失败时必须立即停止,不要继续 Step 1 的下载——否则会下载一堆无法识别的图,浪费时间和磁盘空间。

Parameters

| Parameter | Example | Description | |-----------|---------|-------------| | year | 2023 | 版本年份(非数据年份)。年鉴印制年份 = 数据年份 + 1。用户说"2022 年数据"→ 填 2023;若误填 2022 会拿到 2021 年数据。开工前必须先完成此换算。 | | chapter | 21 | Chapter number; 21=教育, 11=工业, etc. Available chapters vary by edition — probe zk{chapter:02d}.htm to confirm | | out_dir | ./yearbook_data | Output directory for images + Excel |

Step 1: Batch Download

前提:Step 0 多模态自检必须通过。

python scripts/download_yearbook_chapter.py --year {year} --chapter {chapter} --out {out_dir}

The script probes C{chapter:02d}-01.jpg through C{chapter:02d}-NN.jpg until first 404, downloads each image plus the indicator definition zb{chapter:02d}.pdf, and writes manifest.json.

URL pattern (note: NO zk/ prefix; the directory is /html/):

https://www.stats.gov.cn/sj/ndsj/{year}/html/C{chapter:02d}-{num:02d}.jpg
https://www.stats.gov.cn/sj/ndsj/{year}/html/zb{chapter:02d}.pdf
https://www.stats.gov.cn/sj/ndsj/{year}/html/zk{chapter:02d}.htm   (TOC only — `zk` is a filename, not a directory)

Background on the path: see references/url_verification_log.md.

Step 2: Recognize via Multimodal LLM (Read Tool)

前提:Step 0 多模态自检已通过。

Do NOT use traditional OCR (Tesseract / PaddleOCR / EasyOCR) — all fail in sandbox:

  • Tesseract: binary not on PATH
  • PaddleOCR: writes to ~/.paddlex/temp → SANDBOX PERMISSION DENIED
  • EasyOCR: model download times out (WinError 10060)

下载的 zb{chapter:02d}.pdf 是该章的指标定义文件(可选)。若某个表格的列名含义不明确,可用 Read 工具读取该 PDF 获得指标解释。一般情况下直接看图即可,PDF 仅在需要时才读。

For each downloaded JPG, call Read(file_path="{out_dir}/C{chapter:02d}-{NN:02d}.jpg"). The Read tool's multimodal capability returns the table as a natural-language description. From each description, independently extract four elements:

  1. title — 表格顶部标题行(如 "21-1 各级各类学校和教职工情况(2022年)")
  2. unit — 单位行(如 "单位:所、人")——注意有些表的单位是混合的("万人、‰、%")
  3. header — 列标题。单行表头用 ["列1","列2",...];多级表头用 [["组1","组1",...], ["子1","子2",...]]
  4. data — 数据行。每行一个 list;空单元格用 None,数字保持 Python int/float

每张图的描述格式略有不同(甚至同一章内),必须逐张独立解析,不能假设任何固定结构

关键纪律(区分两类失败)

  • 硬失败Read 返回 Content filtered / model does not support images → 当前模型已不是多模态,立即停止识别,重新提示用户切换模型。
  • 软失败Read 返回 synthetic placeholder → 单次异常,重试一次,第二次通常正常;仍失败则 fallback 到 tencentcloud-ocr skill。
  • 无论哪种失败,严禁凭记忆或常识"编造"表格内容——这会产生错误数据并写入 Excel。

识别规则(空值/零值、二级表头扁平化、抽样表标记、跨省排序等)→ 见 references/reference.md § Recognition Tips。

Step 3: Generate Excel

⚠️ 表头来自 OCR,不存在「标准模板」。不同章的表格数量、列名、单位、表头层级完全不同——第21章教育23表、第2章人口15表、第11章工业可能有不同数量且完全不同结构的表。title、unit、header、data 全部来自 Step 2 逐张图的 Read 结果,不存在跨章复用的固定表头库。以下只展示通用的 write_table 调用模式。

代码架构

import sys
from pathlib import Path

SCRIPTS = Path.home() / ".workbuddy" / "skills" / "china-statistical-yearbook-crawler" / "scripts"
sys.path.insert(0, str(SCRIPTS))

from excel_writer_template import write_table, generate_workbook
from openpyxl import Workbook

两种生成模式

模式 A — generate_workbook:所有表共享 total_label

当整章没有跨省表或所有表全国行写法一致时,用 spec 列表批量生成。每个 spec 可单独覆写 total_labelsourcefreeze_panes

specs = [
    {"sheet": "表1", "title": "...(来自OCR)", "unit": "...(来自OCR)",
     "header": [...(来自OCR的列名列表)], "data": [...(来自OCR的数据)],
     "total_label": None},
    {"sheet": "表2", "title": "...(来自OCR)", "unit": "...(来自OCR)",
     "header": [...(来自OCR)], "data": [...(来自OCR)],
     "total_label": "全 国"},  # 仅当该表的 OCR 结果显示第一列为"全 国"(带空格)
]
generate_workbook("all_tables.xlsx", specs)

模式 B — 独立脚本:需要 per-table 定制

当各表差异大(典型的混合章场景,如 snapshot + time series + cross-province 混用),写独立 build_*.py

wb = Workbook()

# 表1:无全国行(snapshot / time series 表)
ws1 = wb.active
write_table(ws1, title="...(来自OCR)", unit="...(来自OCR)",
            header=[...(来自OCR)], data=[...(来自OCR)], total_label=None)

# 表N:有全国行(cross-province 表)
# total_label 必须与 OCR 结果中第一列的实际文字完全一致(包括空格)
ws2 = wb.create_sheet("...(来自OCR的标题)")
write_table(ws2, title="...(来自OCR)", unit="...(来自OCR)",
            header=[...(来自OCR)], data=[...(来自OCR)],
            total_label="全 国")

wb.save("all_tables.xlsx")

关键约定

  • total_label 空格陷阱write_table 默认 total_label="全国"(无空格),但年鉴跨省表第一列常印作 全 国(中间空格)。两者不匹配则全国行不会浅黄高亮。Read 一张跨省表确认第一列的实际文字,再决定传 "全 国" 还是 "全国" 非跨省表通常没有全国行,直接传 total_label=None
  • 数字保持 Python int/float:禁止 "10,145,421" 格式——单位放表头/注释。
  • 多级表头header=[["组1","组1",...], ["子1","子2",...]],同行相同值自动合并。仅当 OCR 结果显示多级表头时才用此格式。完整布局规范 → references/reference.md § Excel Layout。
  • 完整参考实现references/worked_example_c21_2022.py 展示第21章(教育)23 表的完整写法——但 title/header/unit/data 必须替换为你目标章的 OCR 结果,仅借用脚本结构。

验证(不可跳过)

# 1. 内容抽查 — 注意表头是否错乱、关键数字是否合理
python -m markitdown all_tables.xlsx

# 2. 行列完整性 — 以下 Python snippet 确认每个 sheet 非空
python -c "
from openpyxl import load_workbook
wb = load_workbook('all_tables.xlsx')
for ws in wb.worksheets:
    print(f'{ws.title:40s}  {ws.max_row} rows x {ws.max_column} cols')
"

Technical Reference

  • references/reference.md — URL encoding (GBK), network quirks, edition-year vs data-year mapping, table-number gaps, Excel layout spec, and worked table indexes for chapter 21 (Education) and chapter 2 (Population).
  • references/worked_example_c21_2022.py — 第21章(教育)专用参考示例,展示 write_table 调用模式。跨章使用时需将 title/header/unit/data 全部替换为目标章的 OCR 结果,仅复用脚本结构。
  • references/url_verification_log.md — URL path correction log (the directory is /html/, not /zk/html/).
  • assets/multimodal_selfcheck.png — Self-check test image (120x40 RGB color blocks) used by Step 0.