返回 Skill 列表
extension
分类: 数据与分析无需 API Key

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

从中国统计年鉴官网上,下载某个年度(如2023)、某个类别(如教育)的数据,并通过ocr将数据整理到一整张Excel表中

person作者: 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.