爬取中國各地區大學排名變化數據與可視化分析


一、選題背景

              高考作為中國學生生涯中最為重要的事,在高考之后,選擇一所好的大學則是接下的人生的一塊的敲門磚,選擇有着好的大學,和有着良好教育氛圍的城市以及所選擇的大學近年來的變化是很重要的事,在以前,想要了解這些需要翻閱查找大量的資料,而現在我們可以通過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的則能夠相對輕松的得到。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM