一、前言
QS世界大学排名是全球最具影响力的大学排名之一,无论是留学选校、学术研究还是高校竞争力分析,都有重要参考价值。本文将手把手教你用Python完成QS排名的数据爬取、清洗、分析与可视化,从0到1实现完整的数据分析流程,即使是Python新手也能轻松上手。
分析目标
- 爬取2025年QS世界大学排名核心数据(排名、学校名称、国家/地区、总分等);
- 清洗数据,处理缺失值、异常值;
- 分析核心维度:TOP50高校国家分布、不同国家TOP100数量、总分分布等;
- 用可视化图表直观展示分析结果。
二、环境准备
首先安装所需Python库,打开终端执行:
pipinstallrequests beautifulsoup4 pandas matplotlib lxmlrequests:发送HTTP请求爬取网页数据;beautifulsoup4:解析HTML页面,提取目标数据;pandas:数据清洗与分析;matplotlib:数据可视化;lxml:高效的HTML解析器。
三、数据爬取
本文选择爬取QS官网2025年世界大学综合排名(公开可访问页面),核心思路:发送请求→解析页面→提取字段→存储为DataFrame。
完整爬取代码
importrequestsfrombs4importBeautifulSoupimportpandasaspdimporttime# 配置请求头,模拟浏览器访问(避免反爬)headers={"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36","Accept-Language":"zh-CN,zh;q=0.9,en;q=0.8"}# 存储所有数据的列表qs_data=[]# QS2025排名页面(分页爬取,这里爬取前100名,可按需扩展)base_url="https://www.topuniversities.com/rankings/qs-world-university-rankings/2025?page={}"# 爬取前10页(每页10条,共100条)forpageinrange(1,11):try:# 发送请求url=base_url.format(page)response=requests.get(url,headers=headers,timeout=10)response.raise_for_status()# 抛出HTTP错误soup=BeautifulSoup(response.text,"lxml")# 解析页面# 定位排名数据行rank_rows=soup.find_all("div",class_="row indx")forrowinrank_rows:# 提取排名(处理并列排名,如10=)rank_elem=row.find("div",class_="rank")rank=rank_elem.get_text(strip=True)ifrank_elemelseNone# 提取学校名称name_elem=row.find("div",class_="uni-name")university=name_elem.get_text(strip=True)ifname_elemelseNone# 提取国家/地区country_elem=row.find("div",class_="location")country=country_elem.get_text(strip=True)ifcountry_elemelseNone# 提取总分score_elem=row.find("div",class_="overall-score-span")score=score_elem.get_text(strip=True)ifscore_elemelseNone# 存储数据qs_data.append({"排名":rank,"学校名称":university,"国家/地区":country,"总分":score})print(f"第{page}页数据爬取完成,已获取{len(qs_data)}条记录")time.sleep(1)# 延迟1秒,避免请求过快被封IPexceptExceptionase:print(f"第{page}页爬取失败:{str(e)}")continue# 转换为DataFramedf=pd.DataFrame(qs_data)# 保存原始数据到CSV(可选)df.to_csv("qs2025_rank_raw.csv",index=False,encoding="utf-8-sig")print("原始数据爬取完成,已保存为qs2025_rank_raw.csv")print("原始数据前5行:")print(df.head())爬取说明
- 若爬取失败,可检查
User-Agent是否为最新(替换为自己浏览器的UA); - QS官网页面结构可能微调,需根据实际HTML结构修改
class名称; - 爬取更多数据可修改分页范围(如
range(1, 51)爬取前500名)。
四、数据清洗
爬取的原始数据可能存在缺失值、格式异常(如总分是字符串、排名含“=”),需清洗后才能分析。
清洗代码
# 加载原始数据(若已爬取可直接加载)df=pd.read_csv("qs2025_rank_raw.csv",encoding="utf-8-sig")# 1. 处理缺失值:删除关键字段缺失的行df=df.dropna(subset=["排名","学校名称","国家/地区","总分"])print(f"删除缺失值后剩余数据量:{len(df)}")# 2. 清洗排名字段:去除“=”,转换为整数df["排名"]=df["排名"].str.replace("=","").astype(int)# 3. 清洗总分字段:转换为浮点数(处理空值/非数字)defclean_score(score):try:returnfloat(score)except:returnNonedf["总分"]=df["总分"].apply(clean_score)# 删除总分仍为None的行df=df.dropna(subset=["总分"])# 4. 去重:按排名去重(避免重复爬取)df=df.drop_duplicates(subset=["排名"],keep="first")# 5. 重置索引df=df.reset_index(drop=True)# 保存清洗后的数据df.to_csv("qs2025_rank_clean.csv",index=False,encoding="utf-8-sig")print("数据清洗完成,已保存为qs2025_rank_clean.csv")print("清洗后数据前5行:")print(df.head())# 基本数据信息print("\n数据基本信息:")print(df.info())print("\n数据统计描述:")print(df.describe())五、核心数据分析与可视化
5.1 配置可视化环境(解决中文显示问题)
importmatplotlib.pyplotasplt# 设置中文字体(Windows系统)plt.rcParams["font.sans-serif"]=["SimHei"]# 解决负号显示问题plt.rcParams["axes.unicode_minus"]=False# 设置图表风格plt.style.use("ggplot")5.2 分析1:TOP50高校国家/地区分布
# 筛选TOP50数据top50=df[df["排名"]<=50]# 统计国家/地区数量country_count=top50["国家/地区"].value_counts()# 绘制柱状图plt.figure(figsize=(12,6))country_count.plot(kind="bar",color="steelblue")plt.title("2025 QS世界大学排名TOP50 - 国家/地区分布",fontsize=14)plt.xlabel("国家/地区",fontsize=12)plt.ylabel("高校数量",fontsize=12)plt.xticks(rotation=45)plt.tight_layout()# 调整布局避免文字重叠plt.savefig("top50_country_dist.png",dpi=300)plt.show()# 输出统计结果print("TOP50高校国家/地区分布:")print(country_count)5.3 分析2:主要国家TOP100高校数量对比
# 筛选TOP100数据top100=df[df["排名"]<=100]# 筛选主要国家(可按需调整)main_countries=["United States","United Kingdom","China","Japan","Germany","Canada","Australia"]top100_main=top100[top100["国家/地区"].isin(main_countries)]country_count_top100=top100_main["国家/地区"].value_counts()# 绘制饼图plt.figure(figsize=(10,10))plt.pie(country_count_top100.values,labels=country_count_top100.index,autopct="%1.1f%%",startangle=90,colors=plt.cm.Set3.colors)plt.title("2025 QS世界大学排名TOP100 - 主要国家占比",fontsize=14)plt.tight_layout()plt.savefig("top100_country_pie.png",dpi=300)plt.show()print("主要国家TOP100高校数量:")print(country_count_top100)5.4 分析3:TOP100高校总分分布
# 绘制直方图plt.figure(figsize=(10,6))plt.hist(top100["总分"],bins=15,color="lightcoral",edgecolor="black")plt.title("2025 QS世界大学排名TOP100 - 总分分布",fontsize=14)plt.xlabel("总分",fontsize=12)plt.ylabel("高校数量",fontsize=12)plt.axvline(top100["总分"].mean(),color="red",linestyle="--",label=f"平均分:{top100['总分'].mean():.2f}")plt.legend()plt.tight_layout()plt.savefig("top100_score_dist.png",dpi=300)plt.show()# 输出总分统计print("TOP100高校总分统计:")print(f"平均分:{top100['总分'].mean():.2f}")print(f"最高分:{top100['总分'].max():.2f}")print(f"最低分:{top100['总分'].min():.2f}")print(f"中位数:{top100['总分'].median():.2f}")5.5 分析4:中国高校(大陆+港澳台)表现
# 筛选中国高校(大陆、中国香港、中国台湾、中国澳门)china_unis=df[df["国家/地区"].str.contains("China",na=False)]# 按排名排序china_unis_sorted=china_unis.sort_values("排名")print("2025 QS排名中中国高校(TOP100):")print(china_unis_sorted[china_unis_sorted["排名"]<=100][["排名","学校名称","国家/地区","总分"]])# 绘制中国高校TOP100的排名与总分散点图china_top100=china_unis_sorted[china_unis_sorted["排名"]<=100]plt.figure(figsize=(10,6))plt.scatter(china_top100["排名"],china_top100["总分"],color="darkgreen",s=80)# 添加学校名称标注foridx,rowinchina_top100.iterrows():plt.annotate(row["学校名称"],(row["排名"],row["总分"]),fontsize=8,ha="right")plt.title("2025 QS排名TOP100 - 中国高校排名vs总分",fontsize=14)plt.xlabel("排名",fontsize=12)plt.ylabel("总分",fontsize=12)plt.tight_layout()plt.savefig("china_unis_scatter.png",dpi=300)plt.show()六、完整代码整合
将以上步骤整合为一个完整脚本,方便一键运行:
importrequestsfrombs4importBeautifulSoupimportpandasaspdimporttimeimportmatplotlib.pyplotasplt# ===================== 1. 环境配置 =====================# 可视化中文配置plt.rcParams["font.sans-serif"]=["SimHei"]plt.rcParams["axes.unicode_minus"]=Falseplt.style.use("ggplot")# 请求头headers={"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36","Accept-Language":"zh-CN,zh;q=0.9,en;q=0.8"}# ===================== 2. 数据爬取 =====================defcrawl_qs_rank():qs_data=[]base_url="https://www.topuniversities.com/rankings/qs-world-university-rankings/2025?page={}"forpageinrange(1,11):try:url=base_url.format(page)response=requests.get(url,headers=headers,timeout=10)response.raise_for_status()soup=BeautifulSoup(response.text,"lxml")rank_rows=soup.find_all("div",class_="row indx")forrowinrank_rows:rank=row.find("div",class_="rank").get_text(strip=True)ifrow.find("div",class_="rank")elseNoneuniversity=row.find("div",class_="uni-name").get_text(strip=True)ifrow.find("div",class_="uni-name")elseNonecountry=row.find("div",class_="location").get_text(strip=True)ifrow.find("div",class_="location")elseNonescore=row.find("div",class_="overall-score-span").get_text(strip=True)ifrow.find("div",class_="overall-score-span")elseNoneqs_data.append({"排名":rank,"学校名称":university,"国家/地区":country,"总分":score})print(f"第{page}页爬取完成,累计{len(qs_data)}条")time.sleep(1)exceptExceptionase:print(f"第{page}页失败:{e}")continuedf=pd.DataFrame(qs_data)df.to_csv("qs2025_rank_raw.csv",index=False,encoding="utf-8-sig")returndf# ===================== 3. 数据清洗 =====================defclean_data(df):# 删除缺失值df=df.dropna(subset=["排名","学校名称","国家/地区","总分"])# 清洗排名df["排名"]=df["排名"].str.replace("=","").astype(int)# 清洗总分defclean_score(score):try:returnfloat(score)except:returnNonedf["总分"]=df["总分"].apply(clean_score)df=df.dropna(subset=["总分"])# 去重df=df.drop_duplicates(subset=["排名"],keep="first")df=df.reset_index(drop=True)df.to_csv("qs2025_rank_clean.csv",index=False,encoding="utf-8-sig")print("数据清洗完成,保存为qs2025_rank_clean.csv")returndf# ===================== 4. 数据分析与可视化 =====================defanalyze_data(df):# 4.1 TOP50国家分布top50=df[df["排名"]<=50]country_count=top50["国家/地区"].value_counts()plt.figure(figsize=(12,6))country_count.plot(kind="bar",color="steelblue")plt.title("2025 QS TOP50 - 国家/地区分布",fontsize=14)plt.xlabel("国家/地区",fontsize=12)plt.ylabel("数量",fontsize=12)plt.xticks(rotation=45)plt.tight_layout()plt.savefig("top50_country_dist.png",dpi=300)plt.show()# 4.2 主要国家TOP100占比top100=df[df["排名"]<=100]main_countries=["United States","United Kingdom","China","Japan","Germany","Canada","Australia"]top100_main=top100[top100["国家/地区"].isin(main_countries)]country_count_top100=top100_main["国家/地区"].value_counts()plt.figure(figsize=(10,10))plt.pie(country_count_top100.values,labels=country_count_top100.index,autopct="%1.1f%%",startangle=90,colors=plt.cm.Set3.colors)plt.title("2025 QS TOP100 - 主要国家占比",fontsize=14)plt.tight_layout()plt.savefig("top100_country_pie.png",dpi=300)plt.show()# 4.3 TOP100总分分布plt.figure(figsize=(10,6))plt.hist(top100["总分"],bins=15,color="lightcoral",edgecolor="black")plt.axvline(top100["总分"].mean(),color="red",linestyle="--",label=f"平均分:{top100['总分'].mean():.2f}")plt.title("2025 QS TOP100 - 总分分布",fontsize=14)plt.xlabel("总分",fontsize=12)plt.ylabel("数量",fontsize=12)plt.legend()plt.tight_layout()plt.savefig("top100_score_dist.png",dpi=300)plt.show()# 4.4 中国高校表现china_unis=df[df["国家/地区"].str.contains("China",na=False)]china_top100=china_unis[china_unis["排名"]<=100].sort_values("排名")print("中国高校TOP100:")print(china_top100[["排名","学校名称","国家/地区","总分"]])plt.figure(figsize=(10,6))plt.scatter(china_top100["排名"],china_top100["总分"],color="darkgreen",s=80)foridx,rowinchina_top100.iterrows():plt.annotate(row["学校名称"],(row["排名"],row["总分"]),fontsize=8,ha="right")plt.title("2025 QS TOP100 - 中国高校排名vs总分",fontsize=14)plt.xlabel("排名",fontsize=12)plt.ylabel("总分",fontsize=12)plt.tight_layout()plt.savefig("china_unis_scatter.png",dpi=300)plt.show()# ===================== 主函数 =====================if__name__=="__main__":# 爬取数据(若已爬取可注释,直接加载)raw_df=crawl_qs_rank()# 清洗数据clean_df=clean_data(raw_df)# 分析数据analyze_data(clean_df)七、分析结果解读(示例)
- TOP50分布:美国依旧占据主导地位(约20所),英国次之(约8所),中国内地有5所左右进入TOP50;
- TOP100占比:美国占比超40%,英国约15%,中国(含港澳台)约8%;
- 总分分布:TOP100高校总分集中在70-95分区间,前10名总分均超90分,分数差距随排名提升逐渐缩小;
- 中国高校:清华大学、北京大学稳居中国高校榜首,进入TOP20;中国香港的香港大学、香港科技大学也表现亮眼,跻身TOP50。
八、拓展方向
- 爬取历年QS排名数据,分析高校排名变化趋势;
- 加入更多维度分析(如学科排名、师生比、国际生比例等);
- 结合地理信息,绘制全球高校分布热力图;
- 用机器学习预测高校排名变化(如基于总分、学科表现等特征)。
九、注意事项
- 爬取数据时需遵守网站
robots.txt协议,避免高频请求; - QS官网页面结构可能更新,需及时调整爬虫的CSS选择器;
- 数据仅供学习使用,请勿用于商业用途。
总结
本文通过Python完成了QS世界大学排名的全流程分析,从数据爬取到可视化,覆盖了数据分析的核心环节。掌握这套思路后,你可以举一反三,分析其他排名(如泰晤士、U.S. News)或行业数据。希望本文能帮助你提升Python数据分析能力,也为留学选校、高校研究提供参考~