5. **位次口径必须统一**:全校STEM最低位次 = 排除文科+中外合作后,位次最大值(最容易进的专业)
Resources
10Install
npx skillscat add whou17/gaokao-rank-tracker Install via the SkillsCat registry.
SKILL.md
高考录取数据分析技能 (Gaokao Admission & Ranking Tracker)
构建"软科排名 × 学科/专业评级 × 省招考院投档位次"三位一体的高校录取位次综合数据库,支持任意数量专业大类,内置数据核对与验证流程。
触发条件
用户提到高考、录取位次、软科排名、学科评估、专业排名、投档表、择校分析等关键词时激活。
数据架构
三位一体数据结构:
┌─────────────────────────────────────────────────────┐
│ 学校层:排名、所在地、类型、985/211/双一流标签 │
├─────────────────────────────────────────────────────┤
│ 学科层:10+学科 × 前3%/7%/12%/前N名 × 得分×排名 │
├─────────────────────────────────────────────────────┤
│ 专业层:86+专业 × A+/A评级 × 得分×全国排名 │
├─────────────────────────────────────────────────────┤
│ 录取层:分类专业位次 + 全校STEM最低位次 │
└─────────────────────────────────────────────────────┘第零步:加载教育部专业目录(必做)
⚠️ 这是所有后续步骤的基准数据源。跳过此步直接用手工关键词匹配,必然导致专业漏采。
数据源
教育部《普通高等学校本科专业目录》(2026版) — 每年3月发布更新
从目录提取三张映射表
目录结构:学科门类 → 专业类(大类) → 具体专业
提取逻辑:
1. 遍历所有专业类,识别用户目标大类
2. 对每个大类,收集其下所有具体专业代码和名称
3. 建三张表供后续步骤使用表1: 大类→专业代码列表(供第三步软科专业排名爬取)
# 示例输出
{
"电子信息类": ["080701", "080702", "080703", ...], # 22个专业代码
"自动化类": ["080801"], # 1个专业代码
...
}作用:确定要爬哪些软科专业排名URL
表2: 大类→标准专业名列表(供第四步投档表关键词匹配)
# 示例输出
{
"电子信息类": [
"电子信息工程", "电子科学与技术", "通信工程",
"微电子科学与工程", "光电信息科学与工程", "信息工程",
"集成电路设计与集成系统", "人工智能", "水声工程",
"电子封装技术", "电磁场与无线技术", "电波传播与天线",
"电子信息科学与技术", "海洋信息工程", "柔性电子学",
"智能测控工程", "智能视觉工程", "智能视听工程",
"半导体工艺与装备", "广播电视工程", "医学信息工程",
"电信工程及管理" # 共22个
],
...
}作用:替代人工枚举关键词,从目录中系统性提取,确保应采尽采
表3: 专业代码→大类反向索引
# 示例输出
{
"080701": "电子信息类",
"080702": "电子信息类",
...
}作用:拿到一个专业代码,立刻知道属于哪个大类
查缺补漏:目录 vs 软科交叉比对
目录中的专业 - 软科有数据的专业 = 新设专业(尚无排名,如真空工程与技术)
软科有数据的专业 - 目录中的专业 = 目录更新滞后(罕见)这一步在采集前运行,提前告知用户哪些专业无法获取排名数据、原因是什么。
目录文件格式
技能包内置了 references/major_directory_2026.csv,格式:
专业代码,专业名称,专业类代码,专业类名称,学科门类代码,学科门类名称
080701,电子信息工程,0807,电子信息类,08,工学
080702,电子科学与技术,0807,电子信息类,08,工学
...如果目录更新,替换此文件即可,所有映射自动重建。
⚠️ 曾踩过的坑
| 问题 | 根因 | 解决 |
|---|---|---|
| 应急装备技术与工程漏采 | 人工关键词列表不完整,该专业是2024新设 | 以目录为权威来源自动生成关键词 |
| 防灾减灾科学与工程漏采 | 不知道它属于地球物理学类 | 目录反向索引自动归类 |
| 自动化关键词误匹配 | "电气工程及其自动化"含"自动化" | 目录给出精确排除规则 |
| 大类招生名遗漏 | "电子信息类(通信)"不匹配任何具体关键词 | 增加"大类名"作为额外匹配规则 |
第一步:提取软科主榜排名
数据源
软科官网 shanghairanking.cn/rankings/bcur/2025 — 中国大学排名主榜
提取方法
- 使用Playwright(页面JS渲染)爬取前N所学校
- 字段:排名、学校名、所在地、类型(综合/理工/师范等)、总分、标签(985/211/双一流)
- 保存为CSV:
data/软科主榜排名/软科2025主榜_前300.csv
学校名规范化
- 去除编码前缀(如"A001北京大学" → "北京大学")
- 处理括号差异("北京大学(北京)" → "北京大学")
- 特殊情况:中国地质大学分北京/武汉,需保留后缀
第二步:提取学科排名
数据源映射(用户可自定义大类)
学科排名的核心是建立专业大类→软科学科代码的映射:
大类名 → 学科代码列表(从教育部专业目录/软科官网确定)示例映射:
| 专业大类 | 对应学科代码 | 学科名称 |
|---|---|---|
| 电子信息类 | 0809, 0810 | 电子科学与技术, 信息与通信工程 |
| 自动化类 | 0811 | 控制科学与工程 |
| 机械类 | 0802 | 机械工程 |
| 物理学类 | 0702 | 物理学 |
| 力学类 | 0801, 0807 | 力学, 动力工程及工程热物理 |
| 教育学类 | 0401 | 教育学 |
| 地球物理学类 | 0708 | 地球物理学 |
| 测绘类 | 0816 | 测绘科学与技术 |
爬取方法
- URL格式:
https://www.shanghairanking.cn/rankings/bcsr/2025/{学科代码} - 页面JS渲染,需用Playwright
- 提取层次:前3%、前7%、前12% — 以及等效的"前N名"
- ⚠️ 学校数少的学科(如地球物理学10所、测绘28所)用"前2名""前3名"代替百分比,必须一并采集
层次映射
前3% → 顶尖
前2名 → 等效前3%(用于学校总数<67的学科)
前7% → 一流
前3-4名 → 等效前7%
前12% → 优秀采集后核对
- 检查每个学科的level值分布(
Counter) - 确认"前N名"未被遗漏
- 与软科官网页面对比抽样验证
第三步:提取专业排名
数据源映射
每个专业大类下有多个具体专业,需通过教育部普通高等学校本科专业目录确定:
大类 → 专业代码前缀 → 具体专业列表专业排名URL:https://www.shanghairanking.cn/rankings/bcmr/2025/{专业代码}
专业代码→大类映射表
用Python自动建立:
- 读取教育部专业目录CSV
- 按专业类代码前缀分组
- 输出
{大类名: [专业代码列表]}
爬取方法
- 对每个专业代码爬取软科专业排名页面
- 只提取A+和A级记录
- JSON结构:
[{univNameCn, level, totalScore, rank}, ...] - 每专业保存为独立JSON文件
采集后核对
- 统计每个大类下A+和A的总记录数
- 与新设专业列表交叉比对:当年新设专业无排名
- 与教育部目录比对:确认无遗漏专业
第四步:提取省级录取位次
数据源
省级教育考试院发布的投档表XLS/PDF文件
山东省案例:
data/微信导入/山东省2024年普通类常规批第1次志愿投档情况表.xlsdata/微信导入/山东省2025年普通类常规批第1次志愿投档情况表.xls
XLS解析注意事项
- ⚠️ BOM处理:XLS文件可能有BOM头,读取时注意
- ⚠️ 标题行:Row 0通常是合并单元格标题,Row 1才是列头
- ⚠️ 院校代码:如"A001北京大学",需正则去除
re.sub(r'^[A-Z]\d+', '', name) - 列结构:专业名称、院校名称、投档计划数、最低位次
两类提取
A. 按专业大类提取具体专业位次
方法:关键词匹配
- 对每个大类,建立专业名称关键词列表(从教育部专业目录和软科专业名获取)
- 遍历投档表每条记录,用关键词匹配专业类别
- 处理大类招生:专业名以"XX类"开头的归入对应大类
- 取该类下所有匹配专业的最低投档位次(位次最大值=最容易进的专业)
关键词构建原则:
- 正向匹配:专业名包含关键词
- 排除误匹配:如"自动化"排除"电气工程及其自动化""机械设计制造及其自动化"
- 大类招生:专业名如"电子信息类(通信方向)"直接归入对应大类
B. 提取全校STEM最低位次
- 筛选理工科专业:排除明显文科、商科、艺术类专业(用排除关键词列表)
- 排除中外合作办学:
['中外合作','中外','中英','中美','中澳','中加','中法','中德','中日','中韩','合作办学','联合办学'] - 取剩余专业中位次最大值(最容易进的专业)作为STEM最低位次
⚠️ 提取后必须核验
1. 与投档表原始数据对比抽样验证(至少30校)
2. 检查差异>1000的学校
3. 确认排除中外合作办学后逻辑正确
4. 确认文理科判断不误第五步:数据合并与交叉验证
一级核对:基本字段
v4.html 排名 vs 主榜CSV → 逐一比对
v4.html 位次 vs 投档表XLS → 抽样30校比对
v4.html 学科评级 vs bcsr JSON → 交叉比对
v4.html 专业评级 vs bcmr JSON → 抽样20校比对二级核对:来源数据对比
投档表XLS vs 省招考院原始数据 → 非中间产物
软科JSON vs 软科网页 → 抽查10校三级核对:数据一致性
位次口径统一:全部数字为最低位次或全部为最热门位次
学校名统一:含/不含括号、全称/简称
评级层次颜色:全局一致第六步:生成HTML报告
推荐:服务端预渲染
微信等内置浏览器JS支持有限,应采用Python预渲染表格行。
# 数据流程
CSV → Python合并 → 生成HTML(含预渲染<t>行) → JS仅做筛选/搜索关键教训
- 不要用JS动态渲染表格 → 用Python预生成所有HTML行
- 数据嵌入避免特殊字符 → 转义引号
- CSS使用内联style → 兼容性好
- JSON数据用
json.dumps(ensure_ascii=False)→ 避免乱码
扩展性:添加新的大类
- 在教育部专业目录中确认新大类代码和下属专业列表
- 将目录中该大类的专业代码/名称自动导入映射表
- 确定对应的软科学科代码
- 运行学科爬取脚本
- 运行专业爬取脚本(代码列表由目录自动生成,不再人工枚举)
- 关键词匹配规则由目录自动生成
- 重新运行录取位次提取
- 重新运行HTML生成
文件组织
data/
├── 软科主榜排名/
│ └── 软科2025主榜_前300.csv
├── 软科中国最好学科排名/
│ ├── 0809_电子科学与技术.json
│ ├── 0810_信息与通信工程.json
│ └── ...
├── 软科2025中国大学专业排名/
│ ├── raw_080701_电子信息工程.json
│ ├── raw_080702_电子科学与技术.json
│ └── ... (由目录自动生成完整列表)
├── 学科排名验证/ (补充目录)
│ ├── 0807_动力工程及工程热物理.json
│ └── 0816_测绘科学与技术.json
├── 专业录取数据库/
│ ├── 山东省录取位次综合数据库_v3.csv (主榜+位次)
│ ├── 录取位次_按大类提取_v1.csv (分类位次)
│ ├── 山东省录取位次_软科评级_合并_v1.csv (合并)
│ └── 山东省录取位次综合数据库_v5_final.html (成品)
└── 微信导入/
├── 山东省2024年普通类常规批第1次志愿投档情况表.xls
└── 山东省2025年普通类常规批第1次志愿投档情况表_v2.xls核心脚本
参考 /scripts/ 目录下的独立脚本:
01_scrape_school_ranks.py— 爬取软科主榜排名02_scrape_discipline_ranks.py— 爬取学科排名03_scrape_program_ranks.py— 爬取专业排名04_parse_enrollment_table.py— 解析投档表提取位次05_merge_and_verify.py— 合并+核验06_generate_html.py— 生成预渲染HTML
⚠️ 数据质量铁律
- 所有比对必须使用原始数据(省招考院投档表、软科原始API/JSON),严禁以任何中间产物文件为比对基准
- 完成后须事后审计验证数据来源
- 关键矛盾人工最终判决,AI辅助但不替代人工决策
- 版本号随数据同步升级,禁止复用旧版本
- 位次口径必须统一:全校STEM最低位次 = 排除文科+中外合作后,位次最大值(最容易进的专业)