【python大作业/爬虫实战】——基于Python的优志愿大学数据爬虫采集+可视化(附完整代码)

在当今数字化时代,数据采集已成为获取有价值信息的关键手段之一。本篇文章将带你深入了解如何利用Python进行优志愿大学数据的采集,帮助你快速掌握爬虫技术,同时为你在教育领域的数据分析或相关业务拓展提供有力支持。

更新时间:2025-6-29  可用

一、项目背景

随着高考的临近,考生和家长对大学的选择越来越重视。优志愿作为一个提供高考志愿填报辅助的平台,拥有丰富的大学数据,包括学校名称、难易度指数、热度等重要信息。这些数据对于考生选择合适的大学具有重要参考价值。然而,这些数据分散在网页中,手动收集耗时费力。因此,开发一个自动化的数据采集工具,能够高效地获取这些数据,对于需要这些数据进行研究、分析或商业应用的人来说具有重要意义。

二、项目意义

  1. 为考生和家长提供便利:通过采集和整理这些数据,可以为考生和家长提供一个更全面、更直观的大学信息汇总,帮助他们更快地了解不同大学的特点,从而做出更明智的选择。

  2. 助力教育研究:这些数据可以为教育研究者提供丰富的素材,用于分析不同地区、不同类别大学的发展趋势、录取难度变化等,为教育政策的制定和优化提供参考依据。

  3. 商业应用价值:对于教育培训机构、高考志愿填报咨询公司等商业机构来说,这些数据可以作为他们业务拓展的重要资源,帮助他们更好地了解市场需求,制定更精准的营销策略。

三、环境准备

请确保你已安装以下 Python 库:

pip install requests execjs

四、采集字段说明

以下是本项目采集的字段,采集结果会以 CSV 格式保存。

字段名
学校名称大学的全称,是识别大学的关键信息。
难易度指数表示该大学的录取难度,数值越高表示录取难度越大。
热度表示该大学的受欢迎程度,数值越高表示越受考生和家长关注。
所属表示该大学的所属单位,如教育部、地方等。
学校类别表示大学的类型,如综合、理工、师范等。
学校特征表示大学的特色,如211、985、双一流等。
省份大学所在的省份。
城市大学所在的城市。
详情页该大学在优志愿平台上的详细信息页面链接,方便进一步查看详细信息。

五、爬虫思路解析

(一)网页结构分析

官网地址 :优志愿大学信息

数据返回为下滑异步加载,其中请求体有个sign加密参数 挺简单的直接扣;然后请求体主要的就是翻页参数pageIndex   可以采用递归 如果页数小于最大页数就+1

 

(二)反爬机制突破

该网站采用了签名验证机制,关键点在于u-sign参数的生成。先进行js逆向,通过python调用js解密函数进行解密

def get_sign(data):
    result = execjs.compile(js_code).call('get_usign',data)
    return result

(三)基本思路

  1. 分析目标网站:首先,我们需要对优志愿网站的大学数据页面进行分析,了解数据的加载方式、请求参数、响应格式等。通过浏览器的开发者工具,我们可以发现大学数据是通过发送POST请求到特定的API接口获取的,并且请求需要携带一些参数和签名。

  2. 获取签名:由于网站对请求进行了加密签名验证,我们需要使用execjs库来执行网站提供的JavaScript代码,生成合法的签名。这样,我们的请求才能被服务器接受。

  3. 发送请求:使用requests库发送POST请求,将采集到的数据以JSON格式发送到API接口,并在请求头中添加必要的参数和签名。

  4. 解析响应:服务器返回的数据是JSON格式的,我们可以通过json库将其解析为Python字典,然后提取我们需要的字段。

  5. 保存数据:将提取到的数据保存为CSV格式,方便后续查看和分析。我们使用csv库来实现数据的保存。

  6. 分页采集:大学数据是分页显示的,我们需要通过循环逐页采集数据,直到采集完所有页面。在采集过程中,为了避免对服务器造成过大压力,我们使用time.sleep函数控制请求间隔,并使用random.uniform函数生成随机的间隔时间。

六、结果展示

 

 

七、完整代码

(一)数据采集(爬虫)部分

如果你对这个项目感兴趣,想要获取完整可运行的源代码,欢迎在评论区留言或私信(主页 \/)zzxcrq1234 伪善。

(二)可视化
1.中国大学数量区域分布

 

from pyecharts.charts import Map
from pyecharts import options as opts

df_province = df['省份'].value_counts().reset_index()
df_province.columns = ['省份','数量']
data_pair = [(row['省份'], row['数量']) for index, row in df_province.iterrows()]


map_chart = (
    Map()
    .add("", data_pair, maptype="china", is_map_symbol_show=False)  # 不显示标记点
    .set_series_opts(label_opts=opts.LabelOpts(font_size=7))  # 调节省份字体大小
    .set_global_opts(
        title_opts=opts.TitleOpts(title="中国大学数量区域分布图"),
        visualmap_opts=opts.VisualMapOpts(
            is_piecewise=True,  # 分段映射
            pieces=[
                {"max": 50, "label": "50以下", "color": "#E0FFFF"},  
                {"min": 50, "max": 100, "label": "50-100", "color": "#ADFF2F"},  
                {"min": 100, "max": 150, "label": "100-150", "color": "#32CD32"},  
                {"min": 150, "label": "150以上", "color": "#006400"}  
            ]
        )
    )
)
map_chart.render('./可视化结果/中国大学数量区域分布图.html')
map_chart.render_notebook()
 2.大学类别数量柱状图

dic = {}
for i in df['学校类别']:
    if len(eval(i)) == 0:
        continue
    
    for j in eval(i):
        if j.strip() == '其它':
            j='其他'
        if j not in dic:
            dic[j] = 0
        else:
            dic[j] += 1
df_category = pd.DataFrame(list(dic.items()), columns=['类别', '数量'])  
df_category = df_category.sort_values('数量',ascending=False)
# df_category['类别'] = df_category['类别'].map({'其它':'其他'}).fillna(df_category['类别'])
plt.figure(figsize=(12, 8))
barplot = sns.barplot(data=df_category,x='类别',y='数量',palette='viridis')


for bar in barplot.patches:
    yval = bar.get_height()
    barplot.text(bar.get_x() + bar.get_width() / 2, yval, int(yval), ha='center', va='bottom', fontsize=10)
    
plt.title('大学类别数量柱状图',fontsize=15)
plt.xlabel('')
plt.ylabel('')

plt.savefig('./可视化结果/大学类别数量柱状图.jpg')
plt.show()
 3.985、211和双一流大学数量排行榜top7

features_dic = {}
for i in range(len(df)):
    province = df.iloc[i]['省份']
    features = eval(df.iloc[i]['学校特征'])
    for j in features:
        if j in '985':
            features_dic[province] = features_dic.get(province,0) + 1
            break
        elif j == '211':
            features_dic[province] = features_dic.get(province,0) + 1
            break
        elif j == '双一流':
            features_dic[province] = features_dic.get(province,0) + 1
            break
df_good = pd.DataFrame(list(features_dic.items()), columns=['省份', '数量']).sort_values('数量',ascending=False)

plt.figure(figsize=(12, 8))
sns.barplot(data=df_good[:7],x='数量',y='省份',palette='viridis')

plt.title('985、211和双一流大学排行榜top7',fontsize=15)
plt.xlabel('')
plt.ylabel('')
plt.savefig('./可视化结果/985_211和双一流大学排行榜top7.jpg')
plt.show()
4.大学难易度指数分布直方图 

import numpy as np
plt.figure(figsize=(8,8))
sns.distplot(df['难易度指数'], bins=np.arange(1, 100, 1), kde=False,color='g')
plt.title('大学难易度指数分布直方图',fontsize=15)
plt.xlabel('')
plt.ylabel('')

plt.savefig('./可视化结果/大学难易度指数分布直方图.jpg')
plt.show()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值