中國大學排名資料分析與視覺化

临江柔發表於2024-05-29

【題目描述】以軟科中國最好大學排名為分析物件,基於requests庫和bs4庫編寫爬蟲程式,對2015年至2019年間的中國大學排名資料進行爬取:

(1)按照排名先後順序輸出不同年份的前10位大學資訊,並要求對輸出結果的排版進行最佳化;

(2)結合matplotlib庫,對2015-2019年間前10位大學的排名資訊進行視覺化展示。

(3附加)編寫一個查詢程式,根據從鍵盤輸入的大學名稱和年份,輸出該大學相應的排名資訊。如果所爬取的資料中不包含該大學或該年份資訊,則輸出相應的提示資訊,並讓使用者選擇重新輸入還是結束查詢;

【練習要求】請給出原始碼程式和執行測試結果,原始碼程式要求新增必要的註釋。

import requests
from bs4 import BeautifulSoup as bs
import pandas as pd
from matplotlib import pyplot as plt


def get_rank(url):
    count = 0
    rank = []
    headers = {
        "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.54 Safari/537.36 Edg/101.0.1210.3"
    }
    resp = requests.get(url, headers=headers).content.decode()
    soup = bs(resp, "lxml")
    univname = soup.find_all('a', class_="name-cn")
    for i in univname:
        if count != 10:
            university = i.text.replace(" ", "")
            score = soup.select("#content-box > div.rk-table-box > table > tbody > tr:nth-child({}) > td:nth-child(5)"
                                .format(count + 1))[0].text.strip()
            rank.append([university, score])
        else:
            break
        count += 1
    return rank


total = []
u_year = 2015
for i in range(15, 20):
    url = "https://www.shanghairanking.cn/rankings/bcur/20{}11".format(i)
    print(url)
    title = ['學校名稱', '總分']
    df = pd.DataFrame(get_rank(url), columns=title)
    total.append(df)
for i in total:
    plt.rcParams['font.sans-serif'] = ['SimHei']  # 用來正常顯示中文標籤
    x = list(i["學校名稱"])[::-1]
    y = list(i["總分"])[::-1]
    # 1.建立畫布
    plt.figure(figsize=(20, 8), dpi=100)
    # 2.繪製影像
    plt.plot(x, y, label="大學排名")
    # 2.2 新增網格顯示
    plt.grid(True, linestyle="--", alpha=0.5)
    # 2.3 新增描述資訊
    plt.xlabel("大學名稱")
    plt.ylabel("總分")
    plt.title(str(u_year) + "年軟科中國最好大學排名Top10", fontsize=20)
    # 2.5 新增圖例
    plt.legend(loc="best")
    # 3.影像顯示
    plt.savefig(str(u_year)+".png")
    plt.show()

    u_year += 1

while True:
    info = input("請輸入要查詢的大學名稱和年份:")
    count = 0
    university, year = info.split()
    year = int(year)
    judge = 2019 - year
    tmp = total[::-1]
    if 4 >= judge >= 0:
        name = list(total[judge - 1]["學校名稱"])
        for j in name:
            if university == j:
                print(university + "在{0}年排名第{1}".format(year, count + 1))
                break
            count += 1
        if count ==10:
            print("很抱歉,沒有該學校的排名記錄!!!")
            print("請選擇以下選項:")
            print("   1.繼續查詢")
            print("   2.結束查詢")
            select = int(input(""))

            if select == 1:
                continue
            elif select == 2:
                break
        else:
            break
    else:
        print("很抱歉,沒有該年份的排名記錄!!!")
        print("請選擇以下選項:")
        print("   1.繼續查詢")
        print("   2.結束查詢")
        select = int(input(""))

        if select == 1:
            continue
        elif select == 2:
            break

相關文章