# 【实战】Python爬取全国考研数据与可视化(附源码)
一、项目的环境准备一、项目的环境准备pip install requests pandas pyecharts##C整个项目分为两大模块数据爬虫和数据可视化。爬虫模块通过三层接口请求依次获取院校、专业、分数线最终保存为 CSV 文件可视化模块读取 CSV 数据、清洗数据使用pyecharts绘制多类图表并整合展示。第一部分数据爬取分段拆解爬虫采用三层 POST 接口请求下面按功能拆分模块逐个讲解。1.1 导入依赖 初始化全局变量先导入需要的库并定义列表用来存放最终爬取的数据。import random import requests import time import pandas # 定义一个空列表装整体数据 add_data []1.2 配置请求头模拟浏览器防拦截网站接口会校验访问来源配置请求头伪装成正常浏览器访问。# 请求头 h { user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36, referer: https://www.kaoyan.cn/ }1.3 第一层请求获取北京地区院校列表调用接口拿到院校名称、学校唯一 IDprovince_id11代表北京市。# 院校接口地址与请求参数 school_api https://api.kaoyan.cn/pc/school/schoolList school_params { page: 1, limit: 20, province_id: 11, type: , feature: , school_name: } # 发送POST请求解析返回的JSON数据 res_school requests.post(school_api, headersheaders, dataschool_params) school_list res_school.json()[data][data]1.4 遍历院校 第二层请求获取院校专业信息循环每一所学校根据学校 ID 调用接口获取该学校下所有专业信息。# 遍历每一所学校 for school in school_list: school_name school[school_name] school_id school[school_id] print(f正在爬取{school_name}) # 专业接口 请求参数 major_api https://api.kaoyan.cn/pc/school/planListV2 major_params {limit: 5, school_id: school_id} # 请求专业数据 res_major requests.post(major_api, headersheaders, datamajor_params) major_list res_major.json()[data][data]1.5 遍历专业 第三层请求查询专业分数线循环每个专业根据专业 ID 查询分数线增加异常捕获处理无分数的情况。承接上一段循环在内部继续编写# 遍历当前学校下的所有专业 for major in major_list: major_name major[special_name] recruit_num major[recruit_number] study_type major[recruit_type_name] depart major[depart_name] plan_id major[plan_id] # 分数线接口 参数 score_api https://api.kaoyan.cn/pc/school/planDetailV2 score_params {is_apply: 2, plan_id: plan_id} # 请求分数线数据 res_score requests.post(score_api, headersheaders, datascore_params) # 异常捕获部分专业暂无分数线避免程序报错崩溃 try: min_score res_score.json()[data][min_score] except: min_score 暂无1.6 数据组装 延时防反爬把单条数据整理成字典存入列表设置随机休眠降低请求频率。# 组装单条完整数据 row { 学校: school_name, 专业: major_name, 院系: depart, 招生数: recruit_num, 学习方式: study_type, 分数线: min_score } all_data.append(row) # 随机延时 1~3 秒简单规避反爬 time.sleep(random.randint(1, 3))1.7 数据本地持久化保存为 CSV 文件所有数据爬取完成后使用pandas导出为本地表格文件。# 转为DataFrame并保存CSV df pd.DataFrame(all_data) df.to_csv(mnt/北京考研数据.csv, indexFalse, encodingutf-8-sig) print(数据爬取完成已保存)爬虫的完整代码import random import requests import time import pandas # 定义请求网址发送3次请求 # 定义一个空列表。来装每个学校的专业数据 alldata [] # 1.第一个请求网址 以北京城市的大学数据为例子 xxurl https://api.kaoyan.cn/pc/school/schoolList # 请求头 h { user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36, referer: https://www.kaoyan.cn/ } # 传递的信息 xxdata { page: 1, limit: 20, province_id: 11, type: , feature: , school_name: } # 发请求 post请求单独传递的参数复制给data xxres requests.post(urlxxurl, headersh, dataxxdata) xxlist xxres.json()[data][data] # 直接调用json() 需要从学校信息里面获取每个学校名称和唯一id值 for xx in xxlist: xname xx[school_name] print(f开始爬取{xname}的专业) xid xx[school_id] # 携带这个id向该学校的详情页发请求获取对应学校专业 zyurl https://api.kaoyan.cn/pc/school/planListV2 # 专业需要携带的请求发请求 zydata {limit: 5, school_id: xid} # 带上每个学校不同的id号获取对应的专业 # 获取专业发请求 第二次请求 zyres requests.post(urlzyurl, headersh, datazydata) 需要从专业信息里面提取什么和下一步关联是什么 专业招生数学习方式院系 zylist zyres.json()[data][data] # 循环每一个专业提取四个内容找分数线的关键数据 for zy in zylist: zyname zy[special_name] num zy[recruit_number] stype zy[recruit_type_name] departName zy[depart_name] # 从当前每个专业数据里面获取对应专业唯一的id携带id发送第三次请求拿到每个专业的分数线 pid zy[plan_id] 准备发第三次请求携带专业id拿分数线 fsurl https://api.kaoyan.cn/pc/school/planDetailV2 # 准备传递的数据 fsdata {is_apply: 2, plan_id: pid} # 发请求 fsres requests.post(urlfsurl, headersh, datafsdata) # 获取专业分数。某些专业没有分数数据找不到会报错程序崩溃。try捕获报错 try: score fsres.json()[data][min_score] except Exception as e: print(f该专业暂无分数{e}) score 暂无 # 整合数据6个内容 info { 学校: xname, 专业: zyname, 院系: departName, 招生数: num, 学习方式: stype, 分数线: score, } alldata.append(info) # 加一个等待时间避免短时间爬取太快 time.sleep(random.randint(1, 3)) # 存为本地的csv数据 用pandas转数据为表格数据类型 df pandas.DataFrame(alldata) df.to_csv(北京考研数据.csv, indexFalse) print(保存成功)第二部分数据可视化读取上面生成的 CSV 数据做数据清洗 多图表绘制依旧按功能拆分代码。2.1 导入可视化相关库import pandas as pd from pyecharts.charts import Page, Bar, Line from pyecharts import options as opts2.2 读取数据 数据清洗过滤无效数据筛选出 985 院校、全日制的有效数据并转换字段类型。# 读取本地CSV文件 df pd.read_csv(mnt/全国考研数据.csv) # 数据清洗过滤无效值、筛选目标数据 df_clean df[df[招生人数] ! --] df_clean df_clean[df_clean[学习方式] 全日制] df_clean df_clean[df_clean[985] 是] df_clean[招生人数] df_clean[招生人数].astype(int)2.3 模块一绘制专业招生人数 TOP15 柱状图统计热门专业招生总数取前 15 名绘制柱状图并优化 X 轴文字展示。# 分组统计各专业招生总人数倒序取前15 top15_major df_clean.groupby(专业)[招生人数].sum()\ .sort_values(ascendingFalse).head(15)\ .reset_index(name招生总人数) # 创建柱状图对象 bar1 Bar() bar1.add_xaxis(top15_major[专业].tolist()) bar1.add_yaxis(专业招生总人数, top15_major[招生总人数].tolist(), colorred) # 配置X轴文字倾斜、完整展示名称 bar1.set_global_opts( xaxis_optsopts.AxisOpts(axislabel_opts{interval: 0, rotate: 30}) )2.4 模块二筛选金融专业数据单独提取金融专业数据按学校分组统计招生数与最低分数线。# 筛选金融专业所有数据 df_finance df_clean[df_clean[专业] 金融] # 按学校分组聚合计算招生总数、最低分数线 finance_school df_finance.groupby(学校名称).agg( 总招生数(招生人数, sum), 最低分数(分数线, min) ).reset_index().sort_values(最低分数).head(10)2.5 模块三绘制分数线折线图基于上一步处理好的数据绘制院校分数线折线图。# 创建折线图 line Line() line.add_xaxis(finance_school[学校名称].tolist()) line.add_yaxis( 最低分数线, finance_school[最低分数].tolist(), linestyle_optsopts.LineStyleOpts(color#E53E3E) ) # X轴样式优化 line.set_global_opts( xaxis_optsopts.AxisOpts(axislabel_opts{interval: 0, rotate: 30}) )2.6 模块四绘制招生人数柱状图 图表叠加绘制金融专业招生人数柱状图并将折线图叠加在柱状图上实现组合图表。# 创建柱状图招生人数 bar2 Bar() bar2.add_xaxis(finance_school[学校名称].tolist()) bar2.add_yaxis(金融专业招生数, finance_school[总招生数].tolist(), colordata) bar2.set_global_opts( xaxis_optsopts.AxisOpts(axislabel_opts{interval: 0, rotate: 30}) ) # 折线图叠加到柱状图中 bar2.overlap(line)2.7 模块五整合所有图表生成 HTML 文件使用Page容器把多张图表放在同一个页面最终渲染出网页文件。# 创建页面容器 page Page(layoutPage.SimplePageLayout) # 加入所有图表 page.add(bar1, bar2) # 渲染为本地HTML浏览器可直接打开 page.render(考研数据可视化.html) print(图表绘制完成)完整数据可视化代码# 从绘图的库中引入柱状图和折线图 from pyecharts.charts import Page, Bar, Line # 需要安装pip install pyecharts from pyecharts import options as opts import pandas # 读取、清除脏数据、过滤需要的数据 dfData pandas.read_csv(全国考研数据.csv) # 招生人数清洗 newdf dfData[dfData[招生人数] ! --] newdf newdf[newdf[学习方式] 全日制] newdf newdf[newdf[985] 是] # 转换类型 newdf[招生人数] newdf[招生人数].astype(int) # 分组统计不同专业的招生数从高到低取前15个 zydata newdf.groupby(专业)[招生人数].sum().sort_values( ascendingFalse ).head(15).reset_index(name招生总人数) # 创建柱状图 bar Bar() x_data zydata[专业].tolist() y_data zydata[招生总人数].tolist() bar.add_xaxis(x_data) bar.add_yaxis(各专业招生总数, y_data, colorred) # 优化X轴让名称完整显示并倾斜30度 bar.set_global_opts( xaxis_optsopts.AxisOpts( axislabel_opts{ interval: 0, rotate: 30 } ) ) # 查看金融专业的招生情况 major newdf[newdf[专业] 金融] # 按学校聚合招生总数与最低分数 majorschool major.groupby(学校名称).agg( 总招生数(招生人数, sum), 最低分数(分数线, min) ).reset_index() # 按最低分数排序取前10个 resultdata majorschool.sort_values( by最低分数, ascendingTrue ).head(10) # 绘制各学校金融专业分数线对比折线图 x_data resultdata[学校名称].tolist() y_data resultdata[最低分数].tolist() line Line() line.add_xaxis(x_data) line.add_yaxis( 各学校金融专业分数线, y_data, z_level2, linestyle_optsopts.LineStyleOpts(color#E53E3E) ) line.set_global_opts( xaxis_optsopts.AxisOpts( axislabel_opts{ interval: 0, rotate: 30 } ) ) # 绘制各学校金融专业招生人数对比柱状图 y2_data resultdata[总招生数].tolist() bar2 Bar() bar2.add_xaxis(x_data) bar2.add_yaxis(金融专业招生总数对比, y2_data, colordata) bar2.set_global_opts( xaxis_optsopts.AxisOpts( axislabel_opts{ interval: 0, rotate: 30 } ) ) # 把折线图合并到柱状图中 bar2.overlap(line) # 创建装所有图表的容器 page Page(layoutPage.SimplePageLayout) # 把三个图表整合在一个页面里 page.add(bar, line, bar2) # 渲染合成的图表 page.render(考研数据可视化.html) print(绘制结束)三、项目总结爬虫部分采用接口直爬方式分三层请求数据搭配请求头、延时、异常捕获应对基础反爬最终落地为 CSV 表格可视化部分先清洗脏数据再分别绘制柱状图、折线图支持图表叠加与多图合并可视化结果直观易懂拓展方向修改省份 ID 爬取全国数据、增加分页逻辑、新增饼图 / 散点图丰富分析维度。本期内容就分享到这里啦!如果你在实践过程中遇到任何问题或者想获取文中提到的完整源码、 配置文件模板以及更多进阶玩法可扫码领取(无套路纯分享)。

相关新闻

Python网络设备自动配置实战:从备份到批量变更的完整指南

Python网络设备自动配置实战:从备份到批量变更的完整指南

晚上十点,通知群里弹出一条消息:核心机房的一台汇聚设备需要调整接口配置,新增三个业务VLAN的透传,同时把某个下行端口的速率从千兆改成万兆自协商。我打开终端,先翻出设备运维台账,再打开终端工具&#xf…

2026/10/14 5:30:14 阅读更多 →
Android智能指针RefBase/sp/wp底层原理与避坑指南

Android智能指针RefBase/sp/wp底层原理与避坑指南

做Android系统开发这些年,最常打交道的一套内存工具就是平台自带的智能指针:RefBase、sp、wp。跟纯C项目里习惯性用std::shared_ptr不同,Android在Framework、Binder、图形栈等大量native模块里都坚持用这套自研智能指针,这背后有…

2026/10/14 5:29:14 阅读更多 →
UI/UX Pro Max Skill:从需求理解到设计交付的全链路实战指南

UI/UX Pro Max Skill:从需求理解到设计交付的全链路实战指南

做设计这些年,我越来越觉得“UI/UX Pro Max Skill”不是一个具体的软件技巧,而是一整套把产品从“能用”推到“好用”再到“爱用”的能力组合。今天这篇小记,是我自己从需求理解、信息架构、视觉表达到开发交付全链路踩过的坑和攒下的经验&am…

2026/10/14 5:29:14 阅读更多 →

最新新闻

把Antigravity封装成外部Skill,让Codex/Claude Code突破上下文与配额墙

把Antigravity封装成外部Skill,让Codex/Claude Code突破上下文与配额墙

最近在折腾 Codex 和 Claude Code 的混合工作流时,我遇到了一个很实际的问题:单次会话的上下文窗口有限,而一些任务又特别吃资源,反复把代码贴进贴出,很快就撞上了配额墙。后来我想到一个办法——把 Google Antigravit…

2026/10/14 6:16:25 阅读更多 →
AnyPS5:局域网内聚合PS5存档备份、奖杯统计与串流控制的本地工具

AnyPS5:局域网内聚合PS5存档备份、奖杯统计与串流控制的本地工具

最近在做的一个小项目,名字叫 AnyPS5,起因挺朴素的:我自己手头有两台不同型号的主机,平时要在它们之间来回切换着玩。但存档散落在不同设备上,每次都要手动导来导去;想看个奖杯统计,要么开网页等…

2026/10/14 6:16:25 阅读更多 →
项目管理十五至尊图解析与实战应用

项目管理十五至尊图解析与实战应用

1. 项目管理知识体系全景解析在项目管理领域摸爬滚打十几年,我见过太多同行被各种框架图表绕得晕头转向。今天要聊的这个"十五至尊图"堪称项目管理界的"武功秘籍",它把PMBOK的十大知识领域和五大过程组用一张矩阵图完美呈现。第一次…

2026/10/14 6:16:25 阅读更多 →
开源年会进化论:从“同好聚会”到开发者年度节点

开源年会进化论:从“同好聚会”到开发者年度节点

1. 为什么一场开源年会能上得了报纸,还能拿下“最受开发者欢迎”我是在朋友圈刷到这条消息的:COSCon‘25 第十届中国开源年会登上了《中国日报》,同时被思否评为了“最受开发者欢迎的技术活动”。说实话,第一反应不是“厉害”&…

2026/10/14 6:16:25 阅读更多 →
今天周几?JS两行代码背后:getDay()跨语言映射与时区陷阱全解析

今天周几?JS两行代码背后:getDay()跨语言映射与时区陷阱全解析

这个标题我太熟了。刚学编程那阵子,天天在控制台里敲new Date(),盯着那一长串输出发懵:年份、月份、日期、时分秒都在眼前,唯独“今天周几”这个最常用、最直觉的信息,反而要再查一眼文档才能拿到。后来才懂&#xff0…

2026/10/14 6:16:25 阅读更多 →
Java面试必看:3大核心技巧轻松拿offer

Java面试必看:3大核心技巧轻松拿offer

不少朋友常常发送私下消息给我, 向我抱怨说, 他们在参加 Java 这个编程语言相关职位面试的时候, 会碰到一些让人头痛的情况(这里, 我从里面挑选出了几个比较具有代表性的例子来说明):不管是求职还是为了晋升, 面试是我们谁都不能逃避的一件事情。除了低头…

2026/10/14 6:15:24 阅读更多 →

日新闻

AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起:它到底想解决什么问题第一次看到"AnyPS5"这个标题,我脑子里冒出来的第一个念头是:这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述:Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师,我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性,实现了"…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景,也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间,确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中,这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/13 16:22:04 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 22:01:27 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →