20秒縱覽中國大學學術排行榜變化

最近小笨聰在 B 站看到一個展示各國 GDP 排名變化的超燃視頻,當看到中國趕超至世界第一時,那種自豪感油然而生!

微信公衆號原文鏈接  (CSDN不能上傳視頻)

在感嘆的同時,小笨聰也很好奇這類可視化圖表是怎麼製作的?便找到了作者 Jannchie見齊的 B 站主頁:

嗶哩嗶哩 ( ゜- ゜)つロ 乾杯~ Bilibili​space.bilibili.com

 

點進去發現還有大量此類有趣酷炫的視頻。

 

嗯,俺也想學!

那他是怎麼實現的呢?原來他用到了一個動態圖形顯示數據的 JavaScript 庫:D3.js。那麼,如果不會 D3.js 是不是就做不出來了呢?當然不是,Jannchie非常 nice 地給出了一個手把手簡單教程:
見齊 手把手教程

最主要的,他還開放了程序源碼,只需要做2步就能夠實現:

 

  • 打開文件夾裏面的exampe.csv文件,放進你想要展示的數據,再用瀏覽器打開bargraph.html網頁,就可以實現動態效果。只不過要注意使用的數據格式要求。

下面是小笨聰的實例運用。首先爬取大學排行榜的數據並做處理,然後利用源碼將數據可視化。

先提前感受一下效果

 

1.大學排行榜數據爬取

(1)數據來源

世界上最權威的大學排名有4類,分別是:

這裏,我們選取相對比較權威也比較符合國情的第一個 ARWU 的排名結果。打開官網,可以看到有從2003年到2018的英文版和中文版排名,這裏選取中文版。

確定好數據來源,然後就可以把數據爬取下來啦。

(2)分析URL獲取內容

網頁的URL 還是很簡單的,隨着年份變化而變化,我們抓取十年的數據,只需在 main 裏構造一下 for 循環,url 格式如代碼裏所示。另外,需要注意,不同年份網頁採用的編碼不同,返回 response.test 會亂碼,返回response.content 則不會。

 1 def get_one_page(year):
 2    try:
 3        headers = {
 4                'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36'
 5        }
 6        # 英文版
 7        # url = 'http://www.shanghairanking.com/ARWU%s.html' % (str(year))
 8        # 中文版
 9        url = 'http://www.zuihaodaxue.com/ARWU%s.html' % (str(year))
10        response = requests.get(url,headers = headers)
11        # 2009-2015用'gbk',2016-2018用'utf-8'
12        if response.status_code == 200:
13            return response.content
14        return None
15    except RequestException:
16        print('爬取失敗')

(3)解析表格

使用read_html 函數抓取表格,並對錶格進行必要處理。

 1 def parse_one_page(html,i):
 2    tb = pd.read_html(html)[0]
 3    # 重命名錶格列,不需要的列用數字表示
 4    tb.columns = ['world rank','university', 2,3, 'score',4]
 5    tb.drop([2,3],axis = 1,inplace = True)
 6
 7    # rank列100名後是區間,需唯一化,增加一列index作爲排名
 8    tb['index_rank'] = tb.index
 9    tb['index_rank'] = tb['index_rank'].astype(int) + 1
10    # 增加一列年份列
11    tb['year'] = i
12    # read_html沒有爬取country,需定義函數單獨爬取
13    tb['country'] = get_country(html)
14    print(tb) # 測試表格ok
15    return tb
16    print(tb.info()) # 查看錶信息

此時的表格數據並不完整,因爲沒有將國家抓取下來。國家在網頁裏使用圖片表示的,因爲我們可以定位到國家代碼位置。

取下來。國家在網頁裏使用圖片表示的,因爲我們可以定位到國家代碼位置。

可以看到美國是用英文的USA表示的,那麼我們可以單獨提取出src屬性,然後用正則提取出國家名稱就可以了。

 1 def get_country(html):
 2    soup = BeautifulSoup(html,'lxml')
 3    countries = soup.select('td > a > img')
 4    lst = []
 5    for i in countries:
 6        src = i['src']
 7        pattern = re.compile('flag.*\/(.*?).png')
 8        country = re.findall(pattern,src)[0]
 9        lst.append(country)
10    return lst

 

 world rank    university  score     ...       index_rank  year      country
0            1          哈佛大學  100.0     ...                1  2018          USA
1            2         斯坦福大學   75.6     ...                2  2018          USA
2            3          劍橋大學   71.8     ...                3  2018           UK
3            4        麻省理工學院   69.9     ...                4  2018          USA
4            5      加州大學-伯克利   68.3     ...                5  2018          USA
5            6        普林斯頓大學   61.0     ...                6  2018          USA
6            7          牛津大學   60.0     ...                7  2018           UK
7            8        哥倫比亞大學   58.2     ...                8  2018          USA
8            9        加州理工學院   57.4     ...                9  2018          USA
9           10         芝加哥大學   55.5     ...               10  2018          USA
10          11      加州大學-洛杉磯   51.2     ...               11  2018          USA
11          12         康奈爾大學   50.7     ...               12  2018          USA
12          12          耶魯大學   50.7     ...               13  2018          USA
13          14     華盛頓大學-西雅圖   50.0     ...               14  2018          USA
14          15     加州大學-聖地亞哥   47.8     ...               15  2018          USA
15          16       賓夕法尼亞大學   46.4     ...               16  2018          USA
16          17        倫敦大學學院   46.1     ...               17  2018           UK
17          18      約翰霍普金斯大學   45.4     ...               18  2018          USA
18          19     蘇黎世聯邦理工學院   43.9     ...               19  2018  Switzerland
19          20    華盛頓大學-聖路易斯   42.1     ...               20  2018          USA
20          21      加州大學-舊金山   41.9     ...               21  2018          USA
21          22          東京大學   41.5     ...               22  2018        Japan
22          23         多倫多大學   40.9     ...               23  2018       Canada
23          24        倫敦帝國學院   40.1     ...               24  2018           UK
24          25    西北大學(埃文斯頓)   39.9     ...               25  2018          USA
25          26          杜克大學   39.7     ...               26  2018          USA
26          27     密歇根大學-安娜堡   39.4     ...               27  2018          USA
27          28    威斯康星大學-麥迪遜   38.9     ...               28  2018          USA
28          29        哥本哈根大學   38.7     ...               29  2018      Denmark
29          30        洛克菲勒大學   37.9     ...               30  2018          USA

(4)數據處理

將前面生成的 university.csv 文件進一步處理。另外,這次的代碼不僅可以獲得內地大學排名,還可以列出含港澳臺的排名和美國大學的排名。小笨聰也定義了一個 topn 函數,能夠按年份分別求出各年的前20名大學名單。

 1def analysis():
 2    df = pd.read_csv('university.csv')
 3    # 內地
 4    df = df.query("(country == 'China')")[['university','year','index_rank']]
 5
 6    df['index_rank_score'] = df['index_rank']
 7    # 將index_rank列轉爲整形
 8    df['index_rank'] = df['index_rank'].astype(int)
 9    # 含港澳臺
10    # df = df.query("(country == 'China')|(country == 'China-hk')|(country == 'China-tw')|
      # (country == 'China-HongKong')|(country == 'China-Taiwan')|(country == 'Taiwan,China')|(country == 'HongKong,China')")[['university','year','index_rank']]
11    # 美國
12    # df = df.query("(country == 'UnitedStates')|(country == 'USA')")[['university','year','index_rank']]
13    #求topn名
14    def topn(df):
15        top = df.sort_values(['year','index_rank'],ascending = True)
16        return top[:20].reset_index()
17    df = df.groupby(by =['year']).apply(topn)
18    # 更改列順序
19    df = df[['university','index_rank_score','index_rank','year']]
20    # 重命名列
21    df.rename (columns = {'university':'name','index_rank_score':'type','index_rank':'value','year':'date'},inplace = True)
22    # 輸出結果
23    df.to_csv('university_ranking.csv',mode ='w',encoding='utf_8_sig', header=True, index=False)

獲取的表格數據效果如下:

2.數據可視化

首先到 見奇 的 Github 主頁下載源碼,然後將 bargraph.html 拖拽到瀏覽器,點擊 選擇文件,將剛纔下載好的 university_ranking.csv 文件選中,即可看到動態數據圖表。

不過還是有一些需要完善,比如字體大小、柱形顏色、數據項位置、圖表反轉等等,這些參數在源碼的文件裏均可以修改。當然,比較方便的辦法是可以先在該網頁的 css 樣式表裏改,改好後再到源碼裏修改。

源碼有四個方便修改參數的文件:

  • config.js : 配置各功能的開關,比如配色、字體、是否反轉圖表等等;
  • color_ranges.js : 修改柱形圖的顏色;
  • stylesheet.css : 具體修改配色、字體、文字名稱等的 css 樣式;
  • visual.js :更進一步修改,比如圖表透明度。

當然,如果你比較懶,我已經幫你修改好啦(其實也並不是很容易修改...)。

 

以上就是本次爬取大學排行榜數據並製作動態圖標的分析過程。

 

微信公衆號“學編程的金融客”後臺回覆“大學排行榜”即可獲取源碼。

微信公衆號原文鏈接

 

往期推薦

1.自制音樂播放器

2.流浪地球影評

3.北上廣深租房圖鑑

 

你的點贊和關注就是對我最大的支持!

保存掃碼關注公衆號唄

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章