爬取历年中国大学排名(前20名),并随机选取一所高校画图展示其历年总分变化,并计算平均分,在图上展示该平均分直线:
代码如下:
import matplotlib.pyplot as plt
import pandas as pd
import requests
import random
def 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.text
except:
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 #添加一列名称为"年份"的列,其值为i
return 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)
运行结果如下: