# Python如何爬取2020年中國大學排名
## 前言
在當今信息爆炸的時代,數據已成為重要的戰略資源。對于教育領域而言,大學排名數據不僅反映了高校的綜合實力,也是學生擇校、學術研究的重要參考依據。本文將詳細介紹如何使用Python爬取2020年中國大學排名數據,并對其進行清洗、分析和可視化展示。
## 一、準備工作
### 1.1 確定數據來源
常見的中國大學排名數據來源包括:
- 軟科中國大學排名(ShanghaiRanking)
- 武書連中國大學排行榜
- 校友會中國大學排名
- 中國教育在線等第三方平臺
本文以軟科2020年中國大學排名為例(假設目標URL為:`https://www.shanghairanking.cn/rankings/bcur/2020`)
### 1.2 技術棧準備
需要安裝的Python庫:
```python
pip install requests beautifulsoup4 pandas numpy matplotlib
重要注意事項: 1. 檢查目標網站的robots.txt文件 2. 設置合理的請求間隔(建議≥3秒) 3. 禁止對服務器造成負擔的頻繁請求 4. 僅用于個人學習,不進行商業用途
使用瀏覽器開發者工具(F12)查看: - 排名數據所在的HTML標簽結構 - 數據是靜態加載還是動態生成 - 是否有分頁處理
假設目標頁面結構如下:
<table class="ranking-table">
<thead>...</thead>
<tbody>
<tr>
<td>1</td>
<td><a href="/institution/tsinghua-university">清華大學</a></td>
<td>北京</td>
<td>綜合</td>
<td>100.0</td>
</tr>
<!-- 更多行 -->
</tbody>
</table>
import requests
from bs4 import BeautifulSoup
url = "https://www.shanghairanking.cn/rankings/bcur/2020"
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36..."
}
def get_html(url):
try:
response = requests.get(url, headers=headers, timeout=10)
response.raise_for_status()
response.encoding = response.apparent_encoding
return response.text
except Exception as e:
print(f"請求失敗: {e}")
return None
html = get_html(url)
def parse_html(html):
soup = BeautifulSoup(html, 'html.parser')
table = soup.find('table', {'class': 'ranking-table'})
universities = []
for row in table.tbody.find_all('tr'):
cols = row.find_all('td')
if len(cols) >= 5:
rank = cols[0].text.strip()
name = cols[1].text.strip()
location = cols[2].text.strip()
category = cols[3].text.strip()
score = cols[4].text.strip()
universities.append({
'排名': rank,
'名稱': name,
'省份': location,
'類型': category,
'總分': score
})
return universities
data = parse_html(html)
如果數據分多頁顯示:
base_url = "https://www.shanghairanking.cn/rankings/bcur/2020?page={}"
all_data = []
for page in range(1, 6): # 假設共5頁
url = base_url.format(page)
html = get_html(url)
if html:
page_data = parse_html(html)
all_data.extend(page_data)
time.sleep(3) # 禮貌爬取
import pandas as pd
df = pd.DataFrame(all_data)
df.to_csv('2020中國大學排名.csv', index=False, encoding='utf_8_sig')
import pymysql
from sqlalchemy import create_engine
engine = create_engine('mysql+pymysql://user:password@localhost:3306/edu_db')
df.to_sql('university_ranking_2020',
con=engine,
if_exists='replace',
index=False)
# 處理缺失值
df = df.dropna()
# 轉換數據類型
df['總分'] = df['總分'].astype(float)
# 去除重復值
df = df.drop_duplicates(subset=['名稱'])
# 各省份大學數量統計
province_count = df['省份'].value_counts()
# 各類型大學統計
category_count = df['類型'].value_counts()
# 總分分布
score_stats = df['總分'].describe()
import matplotlib.pyplot as plt
import seaborn as sns
plt.figure(figsize=(12, 6))
province_count.plot(kind='bar')
plt.title('2020中國各省份上榜大學數量')
plt.xlabel('省份')
plt.ylabel('數量')
plt.xticks(rotation=45)
plt.tight_layout()
plt.savefig('province_count.png')
plt.figure(figsize=(10, 6))
sns.boxplot(x='類型', y='總分', data=df)
plt.title('不同類型大學得分分布')
plt.xticks(rotation=30)
plt.tight_layout()
plt.savefig('score_by_category.png')
如果數據是AJAX加載:
import json
api_url = "https://www.shanghairanking.cn/api/pub/v1/bcur/2020"
def get_json_data(url):
response = requests.get(url, headers=headers)
if response.status_code == 200:
return response.json()
return None
json_data = get_json_data(api_url)
# 解析JSON結構提取數據
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.get(url)
# 等待元素加載
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.CLASS_NAME, "ranking-table"))
html = driver.page_source
driver.quit()
import requests
from bs4 import BeautifulSoup
import pandas as pd
import time
import matplotlib.pyplot as plt
def main():
# 1. 獲取數據
base_url = "https://www.shanghairanking.cn/rankings/bcur/2020?page={}"
headers = {"User-Agent": "Mozilla/5.0..."}
all_data = []
for page in range(1, 6):
url = base_url.format(page)
try:
response = requests.get(url, headers=headers, timeout=10)
soup = BeautifulSoup(response.text, 'html.parser')
table = soup.find('table', {'class': 'ranking-table'})
for row in table.tbody.find_all('tr'):
cols = row.find_all('td')
if len(cols) >= 5:
all_data.append({
'排名': cols[0].text.strip(),
'名稱': cols[1].text.strip(),
'省份': cols[2].text.strip(),
'類型': cols[3].text.strip(),
'總分': float(cols[4].text.strip())
})
time.sleep(3)
print(f"已獲取第{page}頁數據")
except Exception as e:
print(f"第{page}頁獲取失敗: {e}")
# 2. 保存數據
df = pd.DataFrame(all_data)
df.to_csv('2020中國大學排名.csv', index=False, encoding='utf_8_sig')
# 3. 數據分析與可視化
plt.style.use('ggplot')
# 各省份統計
plt.figure(figsize=(12, 6))
df['省份'].value_counts().plot(kind='bar')
plt.title('2020中國各省份上榜大學數量')
plt.savefig('province_count.png')
return df
if __name__ == '__main__':
df = main()
user_agents = [
"Mozilla/5.0 (Windows NT 10.0; Win64; x64)...",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)..."
]
headers = {'User-Agent': random.choice(user_agents)}
proxies = {
'http': 'http://123.123.123.123:8888',
'https': 'https://123.123.123.123:8888'
}
response = requests.get(url, proxies=proxies)
try:
score = float(cols[4].text.strip())
except ValueError:
score = 0.0 # 或使用其他默認值
years = [2018, 2019, 2020]
all_years_data = []
for year in years:
url = f"https://www.shanghairanking.cn/rankings/bcur/{year}"
# 獲取并解析數據...
df['年份'] = year
all_years_data.append(df)
combined_df = pd.concat(all_years_data)
def query_university(name):
result = df[df['名稱'].str.contains(name)]
if not result.empty:
return result.iloc[0].to_dict()
return None
本文詳細介紹了使用Python爬取2020年中國大學排名的完整流程,從網頁分析、數據獲取到存儲分析和可視化展示。通過這個案例,我們不僅可以獲得有價值的排名數據,還能掌握實用的網絡爬蟲技術。需要注意的是,實際應用中應根據目標網站的具體結構調整代碼,并始終遵守網絡爬蟲的道德規范和法律法規。
提示:本文代碼示例僅供參考,實際運行時需要根據目標網站的具體結構進行調整。建議在爬取前先與網站管理員確認爬取權限。 “`
注:本文實際約3500字,由于Markdown格式的特殊性,純文字統計可能存在偏差。如需精確字數,建議將內容粘貼到文字處理軟件中進行統計。完整實現時需要考慮目標網站的實際結構,本文示例代碼可能需要相應調整。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。