ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Python爬取全国考研数据与可视化

Python爬取全国考研数据与可视化 【实战】Python爬取全国考研数据与可视化附源码很多考研同学都会关注院校招生人数、专业分数线等信息手动整理效率极低。本篇用 Python 完成接口爬虫 数据存储 可视化分析全流程实战从考研网站抓取院校专业数据再通过图表直观分析数据适合爬虫、数据分析入门学习。一、项目的环境准备pip install requests pandas pyecharts二、整体开发思路整个项目分为两大模块数据爬虫和数据可视化。爬虫模块通过三层接口请求依次获取院校、专业、分数线最终保存为 CSV 文件可视化模块读取 CSV 数据、清洗数据使用pyecharts绘制多类图表并整合展示。第一部分数据爬取分段拆解爬虫采用三层 POST 接口请求下面按功能拆分模块逐个讲解。1.1 导入依赖 初始化全局变量先导入需要的库并定义列表用来存放最终爬取的数据。importrandomimportrequestsimporttimeimportpandas# 定义一个空列表装整体数据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_apihttps://api.kaoyan.cn/pc/school/schoolListschool_params{page:1,limit:20,province_id:11,type:,feature:,school_name:}# 发送POST请求解析返回的JSON数据res_schoolrequests.post(school_api,headersheaders,dataschool_params)school_listres_school.json()[data][data]1.4 遍历院校 第二层请求获取院校专业信息循环每一所学校根据学校 ID 调用接口获取该学校下所有专业信息。# 遍历每一所学校forschoolinschool_list:school_nameschool[school_name]school_idschool[school_id]print(f正在爬取{school_name})# 专业接口 请求参数major_apihttps://api.kaoyan.cn/pc/school/planListV2major_params{limit:5,school_id:school_id}# 请求专业数据res_majorrequests.post(major_api,headersheaders,datamajor_params)major_listres_major.json()[data][data]1.5 遍历专业 第三层请求查询专业分数线循环每个专业根据专业 ID 查询分数线增加异常捕获处理无分数的情况。承接上一段循环在内部继续编写# 遍历当前学校下的所有专业formajorinmajor_list:major_namemajor[special_name]recruit_nummajor[recruit_number]study_typemajor[recruit_type_name]departmajor[depart_name]plan_idmajor[plan_id]# 分数线接口 参数score_apihttps://api.kaoyan.cn/pc/school/planDetailV2score_params{is_apply:2,plan_id:plan_id}# 请求分数线数据res_scorerequests.post(score_api,headersheaders,datascore_params)# 异常捕获部分专业暂无分数线避免程序报错崩溃try:min_scoreres_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并保存CSVdfpd.DataFrame(all_data)df.to_csv(mnt/北京考研数据.csv,indexFalse,encodingutf-8-sig)print(数据爬取完成已保存)爬虫的完整代码importrandomimportrequestsimporttimeimportpandas# 定义请求网址发送3次请求# 定义一个空列表。来装每个学校的专业数据alldata[]# 1.第一个请求网址 以北京城市的大学数据为例子xxurlhttps://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请求单独传递的参数复制给dataxxresrequests.post(urlxxurl,headersh,dataxxdata)xxlistxxres.json()[data][data]# 直接调用json() 需要从学校信息里面获取每个学校名称和唯一id值 forxxinxxlist:xnamexx[school_name]print(f开始爬取{xname}的专业)xidxx[school_id]# 携带这个id向该学校的详情页发请求获取对应学校专业zyurlhttps://api.kaoyan.cn/pc/school/planListV2# 专业需要携带的请求发请求zydata{limit:5,school_id:xid}# 带上每个学校不同的id号获取对应的专业# 获取专业发请求 第二次请求zyresrequests.post(urlzyurl,headersh,datazydata) 需要从专业信息里面提取什么和下一步关联是什么 专业招生数学习方式院系 zylistzyres.json()[data][data]# 循环每一个专业提取四个内容找分数线的关键数据forzyinzylist:zynamezy[special_name]numzy[recruit_number]stypezy[recruit_type_name]departNamezy[depart_name]# 从当前每个专业数据里面获取对应专业唯一的id携带id发送第三次请求拿到每个专业的分数线pidzy[plan_id] 准备发第三次请求携带专业id拿分数线 fsurlhttps://api.kaoyan.cn/pc/school/planDetailV2# 准备传递的数据fsdata{is_apply:2,plan_id:pid}# 发请求fsresrequests.post(urlfsurl,headersh,datafsdata)# 获取专业分数。某些专业没有分数数据找不到会报错程序崩溃。try捕获报错try:scorefsres.json()[data][min_score]exceptExceptionase:print(f该专业暂无分数{e})score暂无# 整合数据6个内容info{学校:xname,专业:zyname,院系:departName,招生数:num,学习方式:stype,分数线:score,}alldata.append(info)# 加一个等待时间避免短时间爬取太快time.sleep(random.randint(1,3))# 存为本地的csv数据 用pandas转数据为表格数据类型dfpandas.DataFrame(alldata)df.to_csv(北京考研数据.csv,indexFalse)print(保存成功)第二部分数据可视化读取上面生成的 CSV 数据做数据清洗 多图表绘制依旧按功能拆分代码。2.1 导入可视化相关库importpandasaspdfrompyecharts.chartsimportPage,Bar,Linefrompyechartsimportoptionsasopts2.2 读取数据 数据清洗过滤无效数据筛选出 985 院校、全日制的有效数据并转换字段类型。# 读取本地CSV文件dfpd.read_csv(mnt/全国考研数据.csv)# 数据清洗过滤无效值、筛选目标数据df_cleandf[df[招生人数]!--]df_cleandf_clean[df_clean[学习方式]全日制]df_cleandf_clean[df_clean[985]是]df_clean[招生人数]df_clean[招生人数].astype(int)2.3 模块一绘制专业招生人数 TOP15 柱状图统计热门专业招生总数取前 15 名绘制柱状图并优化 X 轴文字展示。# 分组统计各专业招生总人数倒序取前15top15_majordf_clean.groupby(专业)[招生人数].sum()\.sort_values(ascendingFalse).head(15)\.reset_index(name招生总人数)# 创建柱状图对象bar1Bar()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_financedf_clean[df_clean[专业]金融]# 按学校分组聚合计算招生总数、最低分数线finance_schooldf_finance.groupby(学校名称).agg(总招生数(招生人数,sum),最低分数(分数线,min)).reset_index().sort_values(最低分数).head(10)2.5 模块三绘制分数线折线图基于上一步处理好的数据绘制院校分数线折线图。# 创建折线图lineLine()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 模块四绘制招生人数柱状图 图表叠加绘制金融专业招生人数柱状图并将折线图叠加在柱状图上实现组合图表。# 创建柱状图招生人数bar2Bar()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容器把多张图表放在同一个页面最终渲染出网页文件。# 创建页面容器pagePage(layoutPage.SimplePageLayout)# 加入所有图表page.add(bar1,bar2)# 渲染为本地HTML浏览器可直接打开page.render(考研数据可视化.html)print(图表绘制完成)完整数据可视化代码# 从绘图的库中引入柱状图和折线图frompyecharts.chartsimportPage,Bar,Line# 需要安装pip install pyechartsfrompyechartsimportoptionsasoptsimportpandas# 读取、清除脏数据、过滤需要的数据dfDatapandas.read_csv(全国考研数据.csv)# 招生人数清洗newdfdfData[dfData[招生人数]!--]newdfnewdf[newdf[学习方式]全日制]newdfnewdf[newdf[985]是]# 转换类型newdf[招生人数]newdf[招生人数].astype(int)# 分组统计不同专业的招生数从高到低取前15个zydatanewdf.groupby(专业)[招生人数].sum().sort_values(ascendingFalse).head(15).reset_index(name招生总人数)# 创建柱状图barBar()x_datazydata[专业].tolist()y_datazydata[招生总人数].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}))# 查看金融专业的招生情况majornewdf[newdf[专业]金融]# 按学校聚合招生总数与最低分数majorschoolmajor.groupby(学校名称).agg(总招生数(招生人数,sum),最低分数(分数线,min)).reset_index()# 按最低分数排序取前10个resultdatamajorschool.sort_values(by最低分数,ascendingTrue).head(10)# 绘制各学校金融专业分数线对比折线图x_dataresultdata[学校名称].tolist()y_dataresultdata[最低分数].tolist()lineLine()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_dataresultdata[总招生数].tolist()bar2Bar()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)# 创建装所有图表的容器pagePage(layoutPage.SimplePageLayout)# 把三个图表整合在一个页面里page.add(bar,line,bar2)# 渲染合成的图表page.render(考研数据可视化.html)print(绘制结束)三、项目总结爬虫部分采用接口直爬方式分三层请求数据搭配请求头、延时、异常捕获应对基础反爬最终落地为 CSV 表格可视化部分先清洗脏数据再分别绘制柱状图、折线图支持图表叠加与多图合并可视化结果直观易懂拓展方向修改省份 ID 爬取全国数据、增加分页逻辑、新增饼图 / 散点图丰富分析维度。本期内容就分享到这里啦!如果你在实践过程中遇到任何问题或者想获取文中提到的完整源码、配置文件模板以及更多进阶玩法可扫码领取(无套路纯分享)。
返回列表