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

最近小笨聰在 B 站看到一個展現各國 GDP 排名變化的超燃視頻,當看到中國趕超至世界第一時,那種自豪感油然而生!掘金不能上傳視頻,你們能夠看原文。css

微信公衆號原文連接


在感嘆的同時,小笨聰也很好奇這類可視化圖表是怎麼製做的?便找到了做者 Jannchie見齊的 B 站主頁:space.bilibili.com/1850091/cha…html

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


嗯,俺也想學!
github

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

最主要的,他還開放了程序源碼,只須要作2步就可以實現:瀏覽器


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

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


1.大學排行榜數據爬取

(1)數據來源微信

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

這裏,咱們選取相對比較權威也比較符合國情的第一個 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 :更進一步修改,好比圖表透明度。

固然,若是你比較懶,我已經幫你修改好啦(其實也並非很容易修改...)。

微信公衆號原文連接

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

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

相關文章
相關標籤/搜索