Python实战:中国大学排行榜数据采集与可视化大屏
基于Flask + Vue3 + ECharts构建四大交互式可视化大屏,直接服务于2026年高考志愿填报选校场景。本文仅进行学术交流,如有侵权,请联系作者删除。
完整代码:https://pan.quark.cn/s/d98085527693
一、项目背景:为什么用软科数据做志愿填报可视化
高考志愿填报是每个考生家庭面临的核心决策,而选校的核心依据之一就是大学排名数据。
本项目通过软科官方公开API获取2026年最新排名数据,并以交互式可视化大屏的形式呈现,帮助考生和家长从地域、类型、学科、专业等多个维度筛选目标院校。整个项目包含数据采集、数据清洗、静态图表生成、Web可视化大屏四个完整环节,技术栈覆盖Python数据采集、数据分析、Flask后端、Vue3前端全链路。
项目数据规模
二、软科排名数据从哪来:官方API数据采集实现
前端页面通过Ajax请求加载排名数据,其API接口无需登录验证,可直接调用。本项目数据采集脚本共对接三类API接口,分别对应大学排名(bcur)、学科排名(bcsr)、专业排名(bcmr)。
使用提示:以下代码仅用于个人学习研究,请勿用于商业用途或大规模数据采集,使用时请遵守软科官网的相关条款。
软科API接口说明
| | | |
|---|
| /api/pub/v1/bcur | | |
| /api/pub/v1/bcsr/rank | | |
| /api/pub/v1/bcmr/rank | | |
数据采集的核心逻辑是:先调用类型列表接口获取所有排名类型,再遍历每个类型逐页请求数据,最后将JSON响应展平为结构化DataFrame并保存为CSV文件。以下是大学排名数据采集的核心代码:
# 请求头配置def fetch_json(url, params=None, retries=3, delay=1.0): """带重试的JSON请求""" for attempt in range(retries): try: resp = requests.get(url, headers=HEADERS, params=params, timeout=30) resp.raise_for_status() return resp.json() except Exception as e: print(f" 请求失败(第{attempt+1}次): {e}") if attempt < retries - 1: time.sleep(delay * (attempt + 1)) return Nonedef crawl_ranking(rank_type, year): """获取某个排名类型某年的数据""" data = fetch_json(RANK_API, params={"bcur_type": rank_type["id"], "year": year}) result = data["data"] rankings = result.get("rankings", []) inds = result.get("inds", []) # 构建指标 code -> name 映射 ind_map = {ind["code"]: ind["nameCn"] for ind in inds} rows = [flatten_ranking(r, ind_map, rank_type["nameCn"], year) for r in rankings] return rows, ind_map
每条排名记录经过flatten_ranking函数展平后,包含排名、排名变化、大学名称、省份、大学类型、总分、标签(985/211/双一流)以及10项细分指标得分(办学层次、学科水平、办学资源、师资规模与结构、人才培养、科学研究、服务社会、高端人才、重大项目与成果、国际竞争力)。
关键技术细节:软科API仅为主榜前100名大学提供完整的10项指标得分,排名100之后的大学指标字段为空。这一特性在后端数据处理时需要特别处理——指标雷达图和相关性分析都只使用前100名数据。
三、数据全景:590所大学的六个核心统计
加载主榜590所大学数据后,从规模、层次、分数段、类型、地域、历史趋势六个维度进行统计,以下数据均可在大屏总览页面实时查看。
3.1 高校层次分布:985/211/双一流各有多少所
软科主榜590所大学中,顶尖高校的层次分布如下:
双一流大学(Double First-Class University)是指入选国家"双一流"建设计划的高校,该计划于2017年启动,旨在建设世界一流大学和一流学科。双一流体系在原985/211基础上扩容,但两者高度重合——主榜590所大学中,非211的双一流仅15所,说明双一流与原211体系重合度较高。
3.2 分数段分布:54%的大学总分低于200
软科总分反映大学综合实力,满分约1100分。590所大学的分数段呈明显的长尾分布:
总分最高的是清华大学(1087.1分),平均总分216.18分。319所大学(54%)总分低于200分,而900分以上仅2所,呈现典型的金字塔型质量结构。
3.3 院校类型分布:理工类占主导
理工类院校占比36.4%,反映出中国高等教育的应用型导向。师范类占比26.6%,为志愿填报提供了较大的选择空间。
3.4 地域分布:江苏高校数量最多
各省上榜高校数量Top5:
高校资源呈现"东密西疏、沿海集聚"格局。北京、江苏、上海、山东、浙江为第一梯队,西藏、青海、宁夏、海南等省份上榜高校不足10所。
3.5 历史趋势:哪些大学进步最快
基于2022-2026年五年纵向数据,排名变化最大的院校如下:
进步最大Top5:
退步最大Top5:
进步榜中的温州理工学院、无锡学院、湖州学院均为近年由独立学院转设的公办本科院校,转设后排名大幅上升,值得中段考生关注。
3.6 性价比大学:非985/211但排名靠前
筛选非985、非211、非双一流的大学中排名最靠前的院校,适合中上段考生"捡漏":
南方科技大学位列主榜第30名,是排名最高的非"双一流"高校,其总分466.9甚至超过多所211院校。
四、技术架构:Flask + Vue3 + ECharts 大屏方案
4.1 整体技术栈对比
本项目采用前后端分离架构,后端提供数据API,前端负责可视化渲染:
4.2 后端API设计
Flask后端提供14个API接口,覆盖总览、地域、排名、历史、指标、学科、专业等全部查询场景:
| | |
|---|
/api/overview | | |
/api/province | | |
/api/ranking | | |
/api/history | | |
/api/indicators | | |
/api/university/<name> | | |
/api/subject | | |
/api/major | | |
/api/categories | | |
/api/search | | |
/api/subject/detail | | |
/api/major/detail | | |
/api/strong/universities | | |
后端数据加载的核心代码:
BASE_DIR = os.path.dirname(os.path.abspath(__file__))DATA_DIR = os.path.join(BASE_DIR, 'data')DATA = {}def load_data(): """加载所有CSV数据""" enc = 'utf-8-sig' DATA['main'] = pd.read_csv(os.path.join(DATA_DIR, '软科中国大学排行榜_2026_主榜.csv'), encoding=enc) DATA['all_types'] = pd.read_csv(os.path.join(DATA_DIR, '软科中国大学排行榜_2026_全部类型.csv'), encoding=enc) DATA['history'] = pd.read_csv(os.path.join(DATA_DIR, '软科中国大学排行榜_主榜_历史.csv'), encoding=enc) DATA['subject'] = pd.read_csv(os.path.join(DATA_DIR, '软科中国最好学科排名_2025.csv'), encoding=enc) DATA['major'] = pd.read_csv(os.path.join(DATA_DIR, '软科中国大学专业排名_2026.csv'), encoding=enc) # 解析标签列(985/211/双一流) DATA['main']['标签列表'] = DATA['main']['标签'].fillna('').apply( lambda x: [t for t in str(x).split('/') if t] if x else [])
五、四大可视化大屏详解
项目前端包含四个可视化大屏页面,通过顶部导航切换,每个大屏聚焦一个分析维度。
5.1 总览大屏:核心指标与分数段分布
总览大屏是用户进入系统后的首屏,采用"导航栏 + KPI卡片 + 双图表"的三层布局。顶部展示6个核心指标卡片,中部左侧为分数段柱状图,右侧为院校类型环形图。
6个核心KPI指标:
分数段柱状图直观呈现了长尾分布特征:319所大学(54%)总分低于200分,而900分以上仅2所。这个图表帮助考生快速判断自己的分数段对应多少可选院校。
5.2 地域分析大屏:中国地图可视化与省份下钻
地域分析大屏以ECharts中国地图为核心,用颜色深浅表示各省上榜高校数量。颜色越亮代表高校越多,支持滚轮缩放、拖动平移和点击省份下钻。
地图采用单色系渐变(深蓝到亮青),北京、江苏、上海、山东、浙江为最亮区域。点击任意省份后弹出该省高校明细面板,展示5个统计卡片(上榜高校数、985数、211数、双一流数、平均总分)和完整高校列表。
以四川省为例,点击后展示26所上榜高校的明细:
四川省最强院校为四川大学(排名第15,总分581.3),拥有2所985(四川大学、电子科技大学)和2所纯211(西南交通大学等)。列表中每所大学名称均可点击,进一步下钻到大学详情页。
5.3 院校对比大屏:雷达图与指标相关性
院校对比大屏从三个角度分析大学实力差异:指标雷达图、指标相关性热力图、历史排名趋势图。
雷达图将主榜前100名大学分为三组——顶尖(1-20名)、中段(40-60名)、末段(80-100名),在10个指标维度上对比平均表现,数值归一化到各指标最大值=100。顶尖院校在"学科水平"和"科学研究"维度优势最明显,而中段与末段在"办学层次"维度差距较小。
相关性热力图展示总分与10项指标之间的Pearson相关系数。"学科水平"和"科学研究"与总分的相关性最高,说明这两项指标对大学综合排名的贡献最大。
排名趋势图展示进步最大Top10大学近5年的排名变化轨迹,Y轴反转(排名越小位置越高),直观呈现"潜力股"院校的上升曲线。
5.4 专业学科大屏:838个专业的评级分布
专业学科大屏聚焦学科与专业两个维度,顶部4个KPI卡片展示核心规模数据:
左下图为各学科门类上榜大学数与强势学科数的组合图(柱状+折线),工学以310所上榜大学遥遥领先。右下图为强势学科最多的Top10大学横向条形图,北京大学以36个前10%强势学科位列第一。
专业等级分布:
软科专业等级是软科中国大学专业排名的评级体系,分为A+、A、B+、B四档。A+代表全国前2%(或前2名),是最高等级;A代表前2%-10%;B+代表前10%-20%;B代表前20%-50%。838个专业中仅6.0%获得A+评级,竞争激烈。
强势学科最多Top10大学:
北京大学和清华大学分别拥有36和35个前10%强势学科,形成第一梯队。浙江大学以30个强势学科位居第三,与清北之间存在明显断层。
六、交互下钻:从地图到大学详情的完整链路
本项目的交互设计采用"渐进式披露"原则,用户从宏观到微观逐层下钻,信息密度逐步增加。完整的交互链路如下:
中国地图(宏观) └─ 点击省份 → 省份高校明细面板(中观) └─ 点击大学名称 → 大学详情弹窗(微观) ├─ 核心指标卡片(排名/总分/省份/类型/标签) ├─ 历史排名趋势折线图(5年纵向) ├─ 十大指标雷达图(归一化对比) ├─ 强势学科列表(前10%学科) └─ A级专业列表(A+/A评级专业)
以北京师范大学为例,点击后弹出详情弹窗,展示排名19、总分553.2、标签为"双一流/985/211",以及历史排名趋势(近5年稳定在18-19名)、十大指标雷达图、强势学科(马克思主义理论全国第6、前3%)、A级专业(哲学A等级第6名)等详细信息。
同样,在专业学科大屏中点击任意学科门类,会弹出该门类下的A+专业列表。以教育学门类为例,共72条A+记录,涵盖教育学、体育教育、特殊教育等专业,北京师范大学、华东师范大学等师范类院校占据主导。
七、高考志愿填报的5个数据洞察
基于590所大学的完整数据,以下是5个对志愿填报有直接参考价值的发现。
洞察一:54%的大学总分低于200分,但900分以上仅2所。 软科总分呈金字塔分布,中下段考生可选院校超过400所,而顶尖段(900分以上)只有清华和北大。这意味着高分考生的选择反而更少,需要精挑细选。
洞察二:非985/211中排名最高的是南方科技大学(第30名)。 南方科技大学总分466.9,超过多所211院校,是"双一流"体系外的实力派。上海科技大学(第47名)、深圳大学(第66名)同样值得关注,适合分数较高但无缘传统名校的考生。
洞察三:进步最快的院校多为独立学院转设的公办本科。 温州理工学院5年进步218名,无锡学院进步175名,湖州学院进步173名。这些院校转设后获得更多资源投入,排名快速上升,是中段考生的潜力选择。
洞察四:江苏以39所上榜高校位居各省第一。 江苏高教资源最密集,山东(33所)、河南(31所)紧随其后。但需注意,河南虽然院校数量多,顶尖资源(985/211)相对有限,考生需权衡数量与质量。
洞察五:A+专业仅占6.0%,工学A+数量最多。 在838个专业的31043条参评记录中,A+评级仅1872条(6.0%)。工学门类A+专业数量遥遥领先,反映出工科强校的高度集中。如果目标专业是工学,需要重点关注清华、浙大、哈工大等工科强校。
八、项目完整代码结构
整理后的项目目录结构清晰分为代码、数据、图表、前端四部分:
中国大学排行榜/├── app.py # Flask后端,14个API接口├── crawl_rankings.py # 软科API数据采集脚本(大学/学科/专业三类排名)├── visualize.py # matplotlib静态图表生成(20张)├── data/ # 所有CSV数据文件│ └── 排行榜_2026/ # 15个排名类型的分类型CSV├── img/ # 20张matplotlib静态分析图├── static/ # 前端静态资源│ ├── app.js # Vue3 + ECharts大屏逻辑│ ├── style.css # 深色科技风样式│ └── china.json # 中国地图GeoJSON├── templates/│ └── index.html # 大屏单页应用入口└── 截图/ # 7张大屏交互效果截图
8.1 数据采集脚本的运行方式
脚本支持命令行参数选择采集内容:
python crawl_rankings.py all # 采集全部(大学排名+学科+专业)python crawl_rankings.py ranking # 仅采集大学排名(含5年历史)python crawl_rankings.py subject # 仅采集学科排名python crawl_rankings.py major # 仅采集专业排名
脚本运行后,所有CSV文件自动保存到data/目录,指标说明文件同步生成。
8.2 可视化大屏的启动方式
python app.py# 访问 http://localhost:5000
Flask启动后加载data/目录下的5个核心CSV文件到内存,前端通过14个API接口获取数据,ECharts在nextTick()后初始化渲染(确保DOM已挂载)。
8.3 静态图表生成
python visualize.py# 生成20张分析图到 img/ 目录
静态图表使用matplotlib + seaborn生成,中文字体配置为Microsoft YaHei,涵盖省份分布、分数段、类型对比、指标相关性、排名趋势、学科专业分布等20个分析维度。
九、关键代码片段
9.1 ECharts中国地图配置
// 中国地图初始化const chart = echarts.init(document.getElementById('map-chart'));chart.showLoading();// 加载中国地图GeoJSON$.get('static/china.json', function(geoJson) { echarts.registerMap('china', geoJson); chart.hideLoading(); const option = { backgroundColor: 'transparent', title: { text: '中国高校地域分布地图', left: 'center' }, tooltip: { trigger: 'item', formatter: function(params) { return params.name + ': ' + (params.value || 0) + '所高校'; } }, visualMap: { type: 'continuous', min: 0, max: 100, inRange: { color: ['#1a2a4a', '#00d4ff'] } }, series: [{ type: 'map', mapType: 'china', roam: true, // 支持滚轮缩放和拖动 label: { show: true, fontSize: 9 }, data: provinceData, // 各省高校数量 }] }; chart.setOption(option); // 点击省份下钻 chart.on('click', function(params) { loadProvinceDetail(params.name); // 加载该省高校明细 });});
9.2 进步/退步榜计算逻辑
计算进步榜时必须使用完整的历史数据集,不能在已筛选的DataFrame上操作,否则会导致排名变化计算错误:
@app.route('/api/history')def api_history(): df = DATA['history'].copy() df['排名'] = pd.to_numeric(df['排名'], errors='coerce') # 用完整历史数据计算进步/退步榜 full = df.pivot_table(index='大学名称', columns='年份', values='排名') if 2022 in full.columns and 2026 in full.columns: full = full.dropna(subset=[2022, 2026]) full['变化'] = full[2022] - full[2026] # 正数=进步 # 排除2022已在前30的(变化空间小) improved = full[full[2022] > 30].nlargest(10, '变化') declined = full[full[2022] > 30].nsmallest(10, '变化') # 趋势图展示进步榜Top10的5年排名 trend_df = df[df['大学名称'].isin(improved.index)] pivot = trend_df.pivot_table(index='年份', columns='大学名称', values='排名') # ...返回JSON
9.3 指标雷达图归一化
雷达图只使用主榜前100名(软科仅提供前100的指标数据),并按各指标最大值归一化到0-100:
@app.route('/api/indicators')def api_indicators(): main = DATA['main'].copy() main['排名'] = pd.to_numeric(main['排名'], errors='coerce') # 过滤掉全空的指标列 ind_cols = [c for c in main.columns if c.startswith('指标_')] ind_cols = [c for c in ind_cols if pd.to_numeric(main[c], errors='coerce').notna().sum() > 0] # 只用有指标数据的前100名 top100 = main.nsmallest(100, '排名').copy() # 顶尖/中段/末段分组 groups = { '顶尖(1-20)': top100.nsmallest(20, '排名'), '中段(40-60)': top100[(top100['排名'] >= 40) & (top100['排名'] <= 60)], '末段(80-100)': top100[(top100['排名'] >= 80) & (top100['排名'] <= 100)], } # 归一化到各指标最大值=100 all_vals = top100[ind_cols].apply(pd.to_numeric, errors='coerce') max_vals = all_vals.max() radar_data = {} for name, g in groups.items(): vals = g[ind_cols].apply(pd.to_numeric, errors='coerce').mean() radar_data[name] = [round(float(v / m * 100), 2) if m else 0 for v, m in zip(vals, max_vals)] # ...返回JSON
十、常见问题
985、211、双一流三个层次是什么关系?
985工程(1998年启动)选取39所大学建设世界一流大学;211工程(1995年启动)选取约112所大学重点建设;双一流(2017年启动)在985/211基础上扩容至约147所。三者是递进关系:所有985都是211,所有原211都是双一流,但双一流新增了约35所非211高校。软科主榜590所大学中,985有37所,纯211有60所,非211的双一流仅15所,其余478所为普通本科。
这个可视化大屏如何部署到本地运行?
部署步骤为:安装Python依赖(flask、pandas、numpy),确保data/目录下有5个核心CSV文件,运行python app.py启动Flask服务,浏览器访问http://localhost:5000即可。前端为单页应用,Vue3通过CDN引入,ECharts通过本地文件加载中国地图,无需额外构建步骤。如需重新获取最新数据,运行python crawl_rankings.py all即可。
十一、总结
本项目完整实现了从数据采集到可视化展示的全链路,核心价值在于将软科排名数据转化为面向高考志愿填报的交互式分析工具。项目的五个关键结论:
- 技术架构:Flask提供14个API接口,Vue3 + ECharts渲染四大交互大屏,前后端分离,部署简单。
- 交互设计:实现"地图→省份→大学→指标"的四级下钻,每个层级信息密度递增,符合渐进式披露原则。
- 数据洞察:54%的大学总分低于200分,A+专业仅占6.0%,南方科技大学是非双一流中排名最高的院校(第30名)。