爬取历年中国大学排名(前20名),并随机选取一所高校画图展示其历年总分变化,并计算平均分,在图上展示该平均分直线:
代码如下:
import matplotlib.pyplot as plt
import pandas as pd
import requests
import randomdef main(year):for i in range(2015, year + 1):html = get_one_page(i)if html == '':print('爬取失败')else:tb = parse_one_page(html, i)save_csv(tb)print(i, '年排名提取完成')analysis()#获取网页
def get_one_page(year):try:url='https://www.shanghairanking.cn/rankings/bcur/{}'.format(year)r=requests.get(url,timeout=30)r.raise_for_status()r.encoding='utf-8'return r.textexcept:return ''#在网页上爬取数据
def parse_one_page(html,i):tb=pd.read_html(html)[0]print(tb.to_string())tb.columns=['排名','学校名称',2,3,'总分',5]tb.drop([2,3,5],axis=1,inplace=True) #删除不需要的列tb['年份']=i #添加一列名称为"年份"的列,其值为ireturn tb #返回DataFrame#将DataFrame转化为csv文件
def save_csv(tb):tb.to_csv(r'university_rank.csv',mode='a',encoding='utf-8',header=True,index=0)#绘制图像
def analysis():df = pd.read_csv('university_rank.csv') #读取指定文件csv数据# 选取一个高校进行展示(这里随机选择一个)university = random.choice(df["学校名称"].unique())df = df[df["学校名称"] == university] #将选定学校的数据筛选出来df = df.sort_values('年份', ascending=True) #将年份设为排序的关键字,升序排列#将df中的年份转换为列表,并将列表中的元素转换为整型类型,保存到变量year中year = [int(x) for x in df.loc[:, '年份'].tolist()] #将df中的总分转换为列表,并将列表中的元素保存到rank中rank = [eval(x) for x in df.loc[:, '总分'].tolist()]# 计算平均分avg_score = sum(rank) / len(rank)plt.rcParams['font.sans-serif'] = ['SimHei']#设置折线图,反应不同年份总分变化趋势plt.plot(year, rank, label=university)#绘制平均分的直线,并设置之前的相应性质plt.axhline(y=avg_score, color='r', linestyle='--', label='平均分')#用注释标出平均分数值plt.annotate(f'平均分: {avg_score:.2f}', xy=(year[-1], avg_score), xytext=(10, 10),textcoords='offset points', color='r')plt.xlabel('年份')plt.ylabel('总分')plt.legend()plt.show()#调用main函数
main(2023)
运行结果如下: