爬取中国各地区大学排名变化数据与可视化分析

一、选题背景

              高考作为中国学生生涯中最为重要的事,在高考之后,选择一所好的大学则是接下的人生的一块的敲门砖,选择有着好的大学,和有着良好教育氛围的城市以及所选择的大学近年来的变化是很重要的事,在以前,想要了解这些需要翻阅查找大量的资料,而现在我们可以通过python轻易地了解这些。

 

二、爬虫方案设计

         

1.方案名称:

  中国大学年排名变化数据与可视化分析

2.爬取的内容与数据特征分析:

  通过网站收录的中国大学截止到2019年的排名(因为2020到2021年的疫情对排名变化)

3. 方案概述

  分析网站页面结构,找到爬取数据的位置,根据不同的数据制定不同的爬取方法

三、网站页面结构分析

        

1.网页页面的结构与特性分析

  通过浏览器“审查元素”查看源代码及“网络”反馈

 

 

 

 

 

 

 

 

 

可以看到每一个 tr 里面都有一行数据,这就是所需要的数据,通过 contents 获取标签对里面的数据。

 

 

 

四、爬虫程序设计

     

1. 数据的爬取

 1 import requests
 2 from lxml import html
 3 def Tree(url):
 4     req = requests.get(url)
 5     req.encoding ='utf-8-sig'
 6     allUniv = []
 7     tree = html.fromstring(req.text)
 8     trs = tree.xpath('//tbody/tr')
 9     for tr in trs:
10         tds = tr.xpath('td')
11         if tds == 0:
12             continue
13         oneUniv=[]
14         oneUniv.append(tds[0].text)
15         name = tds[1].xpath('div')
16         oneUniv.append(name[0].text)
17         for td in tds[2:]:
18             oneUniv.append(td.text)
19         allUniv.append(oneUniv)
20     return allUniv
21 
22 url='http://www.zuihaodaxue.cn/zuihaodaxuepaiming2019.html'
23 tree=Tree(url)
24 print("排名   学校名称   省市   总分")
25 for i in range(20):
26      print(tree[i][0],tree[i][1],tree[i][2],tree[i][3],sep='   ')
27 
28 from bs4 import BeautifulSoup
29 def Req(url):
30     req=requests.get(url)
31     req.encoding='utf-8-sig'
32     allUniv=[]
33     soup=BeautifulSoup(req.text,"html.parser")
34     trs=soup.find_all('tr')
35     for tr in trs:
36         tds=tr.find_all('td')
37         if len(tds)==0:
38             continue
39         oneUniv=[]
40         for td in tds:
41             oneUniv.append(td.string)
42         allUniv.append(oneUniv)
43     return allUniv
44 
45 allUniv1=Req(url)
46 print("排名   学校名称   省市   总分")
47 for i in range(20):
48      print(allUniv1[i][0],allUniv1[i][1],allUniv1[i][2],allUniv1[i][3],sep='   ')
49 
50 import matplotlib.pyplot as plt
51 plt.rcParams["font.sans-serif"]=["SimHei"]
52 name=[]
53 sorce=[]
54 for i in range(10):
55     name.append(allUniv1[i][1])
56     sorce.append(float(allUniv1[i][3]))
57 plt.barh(range(len(sorce)),sorce,tick_label=name)
58 plt.title("2019年排名前十位的大学及其总分")
59 plt.xlabel('分数')
60 plt.show()
61 
62 from collections import Counter
63 province=[]
64 for i in range(len(allUniv1)):
65     province.append(allUniv1[i][2])
66 result=Counter(province)
67 print(result)

2.数据简单分析且可视化

    (1)绘制饼状图

1 import matplotlib as mpl
2 mpl.rcParams["font.sans-serif"]=["SimHei"]
3 mpl.rcParams["axes.unicode_minus"]=False
4 plt.pie(result.values(),labels=result.keys(),radius=2)
5 plt.title("各省份大学数量占比饼状图")
6 plt.show()

 

(2)绘制柱状图

     

 1 def dataanly1():
 2     df_score = df.sort_values('score',ascending=False) # asc Flase降序 True升序 ; desc
 3 
 4     name1 = df_score.schoolname[:10]  # x轴坐标
 5     score1 = df_score.score[:10]    # y轴坐标
 6 
 7     plt.bar(range(10),score1,tick_label=name1)  # 绘制条形图,用range()能保持x轴顺序一致
 8     plt.ylim(10,100)
 9     plt.title("大学评分最高Top10",color=colors1)
10     plt.xlabel("大学名称")
11     plt.ylabel("评分")
12 
13     # 标记数值
14     for x,y in enumerate(list(score1)):
15         plt.text(x,y+0.5,'%s' %round(y,1),ha='center',color=colors1)
16         pass
17 
18     pl.xticks(rotation=270) # 旋转270°
19     plt.tight_layout()  # 去除空白
20 
21     plt.show()
22 def DXAnly2():
23     area_count = df.groupby(by='area').area.count().sort_values(ascending=False)
24     # 绘图方法1
25     area_count.plot.bar(color='#4652B1')  # 设置为蓝紫色
26     pl.xticks(rotation=0)  # x轴名称太长重叠,旋转为纵向
27     for x, y in enumerate(list(area_count.values)):
28         plt.text(x, y + 0.5, '%s' % round(y, 1), ha='center', color=colors1)
29     plt.title('各地区大学数量排名')
30     plt.xlabel('地区')
31     plt.ylabel('数量(所)')
32     plt.show()

 

 1 def dataanly1():
 2 
 3     df_score = df.sort_values('score',ascending=False) # asc Flase降序 True升序 ; desc
 4 
 5     name1 = df_score.schoolname[:10]  # x轴坐标
 6 
 7     score1 = df_score.score[:10]    # y轴坐标
 8 
 9     plt.bar(range(10),score1,tick_label=name1)  # 绘制条形图,用range()能保持x轴顺序一致
10     plt.ylim(10,100)
11 
12     plt.title("大学评分最高Top10",color=colors1)
13 
14     plt.xlabel("大学名称")
15 
16     plt.ylabel("评分")
17 
18     # 标记数值
19     for x,y in enumerate(list(score1)):
20         plt.text(x,y+0.5,'%s' %round(y,1),ha='center',color=colors1)
21         pass
22 
23     pl.xticks(rotation=270) # 旋转270°
24    
25    plt.tight_layout()  # 去除空白
26 
27     plt.show()

 

 

 

 

     通过所绘制柱状图与饼状图,我们可以清晰地看出优秀大学在各个省份占比,在选择大学的时候,可以优先选择教育资源更加多源,高等教育水平更高的省份城市,

其中前三名的地区是北京、江苏、上海,经济水平较为发达的地区,可以简单的看见高素质教育水平可以影响地区经济的发展。

(4)绘制折线图

 1 from pyecharts.charts import Line
 2 from pyecharts import options as opts
 3 
 4 line = (
 5     Line()
 6     .add_xaxis(top10_sum.index.tolist())
 7     .add_yaxis("总分", top10_sum["总分"].astype('int').tolist())
 8     .set_global_opts(title_opts=opts.TitleOpts(title="中国最好大学TOP10(各省份)" ,subtitle="总分"))
 9 )
10 line.render_notebook()

 

 

 

 

(5)绘制词云

         

 1 from PIL import Image
 2 from os import path
 3 from wordcloud import WordCloud
 4 wordcloud=WordCloud(
 5     background_color = '#f3f3f3',
 6     font_path = 'C:\Windows\Fonts\msyh.ttc',
 7     margin=3,
 8     max_font_size=60,
 9     random_state=50,
10     scale=10,
11     colormap='viridis',
12     
13 )
14 wordcloud.generate_from_frequencies(result)
15 plt.imshow(wordcloud,interpolation = 'bilinear')
16 plt.axis('off')
17 plt.show()

 (6)各省市大学数量平均分纵向柱状图

 1 df1.sort_values(by=['平均分'], ascending=False, inplace=True)
 2 d1 = df1.index.tolist()
 3 d2 = df1['数量'].values.tolist()
 4 d3 = df1['平均分'].values.tolist()
 5 
 6 bar0 = (
 7     Bar()
 8     .add_xaxis(d1)
 9     .add_yaxis('数量', d2)
10     .add_yaxis('平均分数', d3)
11     .set_global_opts(
12         title_opts=opts.TitleOpts(title='中国大学排名'),
13         yaxis_opts=opts.AxisOpts(name=''),
14         xaxis_opts=opts.AxisOpts(name='省份'),
15     )
16 )

 

 

 

(7)各省市大学数量平均分横向柱状图

       

 1 df1.sort_values(by=['平均分'], inplace=True)
 2 
 3 d1 = df1.index.tolist()
 4 d2 = df1['数量'].values.tolist()
 5 d3 = df1['平均分'].values.tolist()
 6 
 7 bar1 = (
 8     Bar()
 9     .add_xaxis(d1)
10     .add_yaxis('数量', d2)
11     .add_yaxis('平均分数', d3)
12     .reversal_axis()
13     .set_series_opts(label_opts=opts.LabelOpts(position='right'))
14     .set_global_opts(
15         title_opts=opts.TitleOpts(title='中国大学排名'),
16         yaxis_opts=opts.AxisOpts(name='省份'),
17         xaxis_opts=opts.AxisOpts(name=''),
18     )
19 )

 

 

 

(8)绘制玫瑰图

   

 1 name = df_counts.index.tolist()
 2 
 3 count = df_counts.values.tolist()
 4 
 5 c0 = (
 6     Pie()
 7     .add(
 8         '',
 9         [list(z) for z in zip(name, count)],
10         radius=['20%', '60%'],
11         center=['50%', '65%'],
12         rosetype="radius",
13         label_opts=opts.LabelOpts(is_show=False),
14     )
15     .set_series_opts(label_opts=opts.LabelOpts(formatter='{b}: {c}'))
16 )

(9)大学地图分布

       

 1 name = df0.index.tolist()
 2 
 3 count = df0.values.tolist()
 4 
 5 m = (
 6         Map()
 7         .add('', [list(z) for z in zip(name, count)], 'china')
 8         .set_global_opts(
 9             title_opts=opts.TitleOpts(title='中国大学排名'),
10             visualmap_opts=opts.VisualMapOpts(max_=40, split_number=8, is_piecewise=True),
11         )
12     )

 

 

 

 

 

 

(10)选定绘制折线图

       选择一所大学,查看这所大学今年来的排名变化,这里选择北京邮电大学

   

 1 sorce2=[]
 2 for i in range(4):
 3     url='http://www.zuihaodaxue.cn/zuihaodaxuepaiming'+str(i+2016)+'.html'
 4     allUniv=Req(url)
 5     for i in range(len(allUniv)):
 6         if  allUniv[i][1]=="北京邮电大学":
 7             j=i
 8             break
 9     sorce2.append(float(allUniv[j][3])) 
10 print(sorce2)
11 
12 years=[2016,2017,2018,2019]
13 plt.subplot(1,1,1)
14 plt.plot(years,sorce2,marker='o')
15 plt.grid(True)
16 plt.title("北京邮电大学2016-2019年评分走势")
17 plt.xlabel('')
18 plt.ylabel('分数')
19 plt.show()

 

 

五、代码汇总

      

  1 import requests
  2 from lxml import html
  3 
  4 def Tree(url):
  5     req = requests.get(url)
  6     req.encoding ='utf-8-sig'
  7     allUniv = []
  8 
  9     tree = html.fromstring(req.text)
 10     trs = tree.xpath('//tbody/tr')
 11     
 12      for tr in trs:
 13         tds = tr.xpath('td')
 14         if tds == 0:
 15             continue
 16         oneUniv=[]
 17         oneUniv.append(tds[0].text)
 18         name = tds[1].xpath('div')
 19         oneUniv.append(name[0].text)
 20 
 21         for td in tds[2:]:
 22             oneUniv.append(td.text)
 23         allUniv.append(oneUniv)
 24     return allUniv
 25 
 26    
 27   url='http://www.zuihaodaxue.cn/zuihaodaxuepaiming2019.html'
 28   tree=Tree(url)
 29   print("排名   学校名称   省市   总分")
 30   for i in range(20):
 31      print(tree[i][0],tree[i][1],tree[i][2],tree[i][3],sep='   ')
 32 
 33  from bs4 import BeautifulSoup
 34 
 35 def Req(url):
 36     req=requests.get(url)
 37     req.encoding='utf-8-sig'
 38     allUniv=[]
 39     soup=BeautifulSoup(req.text,"html.parser")
 40     trs=soup.find_all('tr')
 41    
 42      for tr in trs:
 43         tds=tr.find_all('td')
 44         if len(tds)==0:
 45             continue
 46 
 47         oneUniv=[]
 48         for td in tds:
 49             oneUniv.append(td.string)
 50         allUniv.append(oneUniv)
 51 
 52     return allUniv
 53    allUniv1=Req(url)
 54    print("排名   学校名称   省市   总分")
 55    for i in range(20):
 56      print(allUniv1[i][0],allUniv1[i][1],allUniv1[i][2],allUniv1[i][3],sep='   ')
 57 
 58 import csv
 59 
 60 with open('text2019.csv', 'w',newline='') as csvfile:
 61     writer = csv.writer(csvfile)
 62     writer.writerow(['排名','学校名称','省市','总分','指标得分','生源质量(新生高考成绩得分)','培养结果(毕业生就业率)','社会声誉(社会捐赠收入·千元)','科研规模(论文数量·篇)','科研质量(论文质量·FWCI)','顶尖成果(高被引论文·篇)','顶尖人才(高被引学者·人)','科技服务(企业科研经费·千元)','成果转化(技术转让收入·千元)'])
 63     for row in allUniv1:
 64         writer.writerow(row)
 65 
 66 import matplotlib.pyplot as plt
 67 
 68 plt.rcParams["font.sans-serif"]=["SimHei"]
 69 name=[]
 70 sorce=[]
 71 
 72 for i in range(10):
 73     name.append(allUniv1[i][1])
 74     sorce.append(float(allUniv1[i][3]))
 75 plt.barh(range(len(sorce)),sorce,tick_label=name)
 76 plt.title("2019年排名前十位的大学及其总分")
 77 plt.xlabel('分数')
 78 plt.show()
 79 
 80 from collections import Counter
 81 
 82 province=[]
 83 for i in range(len(allUniv1)):
 84     province.append(allUniv1[i][2])
 85 result=Counter(province)
 86 print(result)
 87 
 88 import matplotlib as mpl
 89 
 90 mpl.rcParams["font.sans-serif"]=["SimHei"]
 91 mpl.rcParams["axes.unicode_minus"]=False
 92 plt.pie(result.values(),labels=result.keys(),radius=2)
 93 plt.title("各省份大学数量占比饼状图")
 94 
 95 from PIL import Image
 96 from os import path
 97 from wordcloud import WordCloud
 98 
 99 wordcloud=WordCloud(
100     background_color = '#f3f3f3',
101     font_path = 'C:\Windows\Fonts\msyh.ttc',
102     margin=3,
103     max_font_size=60,
104     random_state=50,
105     scale=10,
106     colormap='viridis',
107     
108 )
109 wordcloud.generate_from_frequencies(result)
110 plt.imshow(wordcloud,interpolation = 'bilinear')
111 
112 plt.axis('off')
113 plt.show()
114 plt.show()
115 
116 def dataanly1():
117     df_score = df.sort_values('score',ascending=False) # asc Flase降序 True升序 ; desc
118 
119     name1 = df_score.schoolname[:10]  # x轴坐标
120     score1 = df_score.score[:10]    # y轴坐标
121 
122     plt.bar(range(10),score1,tick_label=name1)  # 绘制条形图,用range()能保持x轴顺序一致
123     plt.ylim(10,100)
124     plt.title("大学评分最高Top10",color=colors1)
125     plt.xlabel("大学名称")
126     plt.ylabel("评分")
127 
128     # 标记数值
129     for x,y in enumerate(list(score1)):
130         plt.text(x,y+0.5,'%s' %round(y,1),ha='center',color=colors1)
131         pass
132 
133     pl.xticks(rotation=270) # 旋转270°
134     plt.tight_layout()  # 去除空白
135 
136     plt.show()
137 
138 def DXAnly2():
139     area_count = df.groupby(by='area').area.count().sort_values(ascending=False)
140     # 绘图方法1
141 
142     area_count.plot.bar(color='#4652B1')  # 设置为蓝紫色
143     pl.xticks(rotation=0)  # x轴名称太长重叠,旋转为纵向
144     for x, y in enumerate(list(area_count.values)):
145         plt.text(x, y + 0.5, '%s' % round(y, 1), ha='center', 
146 color=colors1)
147 
148     plt.title('各地区大学数量排名')
149     plt.xlabel('地区')
150     plt.ylabel('数量(所)')
151     plt.show()
152 
153 from PIL import Image
154 from os import path
155 from wordcloud import WordCloud
156 
157 wordcloud=WordCloud(
158     background_color = '#f3f3f3',
159     font_path = 'C:\Windows\Fonts\msyh.ttc',
160     margin=3,
161     max_font_size=60,
162     random_state=50,
163     scale=10,
164     colormap='viridis',
165     
166 )
167 wordcloud.generate_from_frequencies(result)
168 plt.imshow(wordcloud,interpolation = 'bilinear')
169 plt.axis('off')
170 plt.show()
171 
172 from pyecharts.charts import Line
173 from pyecharts import options as opts
174 
175 line = (
176     Line()
177     .add_xaxis(top10_sum.index.tolist())
178     .add_yaxis("总分", top10_sum["总分"].astype('int').tolist())
179     .set_global_opts(title_opts=opts.TitleOpts(title="中国最好大学TOP10(各省份)" ,subtitle="总分"))
180 )
181 line.render_notebook()
182 
183 df1.sort_values(by=['平均分'], ascending=False, inplace=True)
184 d1 = df1.index.tolist()
185 d2 = df1['数量'].values.tolist()
186 d3 = df1['平均分'].values.tolist()
187 
188 bar0 = (
189     Bar()
190     .add_xaxis(d1)
191     .add_yaxis('数量', d2)
192     .add_yaxis('平均分数', d3)
193     .set_global_opts(
194         title_opts=opts.TitleOpts(title='中国大学排名'),
195         yaxis_opts=opts.AxisOpts(name=''),
196         xaxis_opts=opts.AxisOpts(name='省份'),
197     )
198 )
199 
200 df1.sort_values(by=['平均分'], inplace=True)
201 
202 d1 = df1.index.tolist()
203 d2 = df1['数量'].values.tolist()
204 d3 = df1['平均分'].values.tolist()
205 
206 bar1 = (
207     Bar()
208     .add_xaxis(d1)
209     .add_yaxis('数量', d2)
210     .add_yaxis('平均分数', d3)
211     .reversal_axis()
212     .set_series_opts(label_opts=opts.LabelOpts(position='right'))
213     .set_global_opts(
214         title_opts=opts.TitleOpts(title='中国大学排名'),
215         yaxis_opts=opts.AxisOpts(name='省份'),
216         xaxis_opts=opts.AxisOpts(name=''),
217     )
218 )
219 
220 
221 name = df_counts.index.tolist()
222 
223 count = df_counts.values.tolist()
224 
225 c0 = (
226     Pie()
227     .add(
228         '',
229         [list(z) for z in zip(name, count)],
230         radius=['20%', '60%'],
231         center=['50%', '65%'],
232         rosetype="radius",
233         label_opts=opts.LabelOpts(is_show=False),
234     )
235     .set_series_opts(label_opts=opts.LabelOpts(formatter='{b}: {c}'))
236 )
237 
238 
239 
240 name = df0.index.tolist()
241 
242 count = df0.values.tolist()
243 
244 m = (
245         Map()
246         .add('', [list(z) for z in zip(name, count)], 'china')
247         .set_global_opts(
248             title_opts=opts.TitleOpts(title='中国大学排名'),
249             visualmap_opts=opts.VisualMapOpts(max_=40, split_number=8, is_piecewise=True),
250         )
251     )
252 
253 
254 sorce2=[]
255 for i in range(4):
256     url='http://www.zuihaodaxue.cn/zuihaodaxuepaiming'+str(i+2016)+'.html'
257     allUniv=Req(url)
258     for i in range(len(allUniv)):
259         if  allUniv[i][1]=="北京邮电大学":
260             j=i
261             break
262     sorce2.append(float(allUniv[j][3])) 
263 print(sorce2)
264 
265 years=[2016,2017,2018,2019]
266 plt.subplot(1,1,1)
267 plt.plot(years,sorce2,marker='o')
268 plt.grid(True)
269 plt.title("北京邮电大学2016-2019年评分走势")
270 plt.xlabel('')
271 plt.ylabel('分数')
272 plt.show()

 

六、总结

         一所好的大学,对人生的影响是非常巨大的,在力所能及的范围内选择一所位于教育资源更加多源,高等教育水平更高的省份城市的优秀大学是非常重要的事,作为判断标准的数据,在以往单单是一所大学的相关资料就需要通过大量、繁琐的查找与翻阅才能够得到,若是多所大学的多年的变化则需要更多的时间。而现在通过python的则能够相对轻松的得到。

 

posted @ 2021-06-19 13:02  檀鲁辉  阅读(1947)  评论(0编辑  收藏  举报