今天我学习的是爬虫与数据分析结合,还练习了以下案例
一、案例
本次案例以中国大学排名数据为研究对象,通过爬虫技术从高三网(网址:2021中国的大学排名一览表_高三网)爬取学校名称、总分、全国排名、星级排名、办学层级等信息,将数据保存为 CSV 文件后,进行数据预处理与可视化分析,完整展现了从数据获取到数据分析的全流程。
二、中国大学排名爬取实现
(一)任务分析
目标网页包含结构化的大学排名表格数据,通过分析网页 HTML 结构可知,数据存储在table>tbody>tr
标签中,每个tr
标签下的td
标签分别对应名次、学校名称、总分等信息,可通过解析这些标签提取目标数据。
(二)代码实现
- 获取网页数据
python
运行
import requests
def get_html(url, time=3): # get请求通用函数
try:
r = requests.get(url, timeout=time) # 发送请求
r.encoding = r.apparent_encoding # 设置返回内容的字符集编码
r.raise_for_status() # 返回的状态码不等于200抛出异常
return r.text # 返回网页的文本内容
except Exception as error:
print(error)
- 解析网页数据
python
运行
from bs4 import BeautifulSoup
def parser(html): # 解析函数
soup = BeautifulSoup(html, "lxml") # html转换为soup对象
out_list = [] # 解析函数输出数据的列表
for row in soup.select("table>tbody>tr"): # 循环遍历tr
td_html = row.select("td") # 获取td
row_data = [
td_html[1].text.strip(), # 学校名称
td_html[2].text.strip(), # 总分
td_html[3].text.strip(), # 全国排名
td_html[4].text.strip(), # 星级
td_html[5].text.strip(), # 办学层次
]
out_list.append(row_data) # 将解析的每行数据插入到输出列表中
return out_list
- 保存数据到 CSV
python
运行
import csv
def save_csv(item, path): # 数据存储,将List数据写入文件
with open(path, "wt", newline="", encoding="utf-8") as f: # 创建utf8编码文件
csv_write = csv.writer(f) # 创建写入对象
csv_write.writerows(item) # 一次性写入多行
if __name__ == "__main__":
url = "http://www.bspider.top/gaosan/"
html = get_html(url) # 获取网页数据
out_list = parser(html) # 解析网页,输出列表数据
save_csv(out_list, "school.csv") # 数据存储
- 运行结果
生成的school.csv
文件包含爬取的大学数据,示例内容如下:
plaintext
学校名称,总分,全国排名,星级排名,办学层次
北京大学,100,1,8★,世界一流大学
清华大学,99.81,2,8★,世界一流大学
浙江大学,80.72,4,8★,世界一流大学
...
三、数据预处理
针对school.csv
中 “总分” 列存在的空数据,使用 pandas 进行处理:
- 删除包含空字段的行
python
运行
import pandas as pd
df = pd.read_csv("school.csv")
new_df = df.dropna()
print(new_df.to_string())
- 用指定内容替换空字段
python
运行
import pandas as pd
df = pd.read_csv("school.csv")
df.fillna("暂无分数信息", inplace=True)
print(df.to_string())
- 用列的均值替换空单元格
python
运行
import pandas as pd
df = pd.read_csv("school.csv")
x = df["总分"].mean()
print("总分的均值为")
print(x)
df["总分"].fillna(x, inplace=True)
print(df.to_string())
- 用列的中位数替换空单元格
python
运行
import pandas as pd
df = pd.read_csv("school.csv")
x = df["总分"].median()
print("总分的中位数为")
print(x)
df["总分"].fillna(x, inplace=True)
print(df.to_string())
四、数据分析与可视化
(一)柱形图可视化不同星级学校数量
- 垂直柱形图
python
运行
import matplotlib.pyplot as plt
import numpy as np
x = np.array(["8星", "7星", "6星", "5星", "4星", "3星", "2星", "1星"])
y = np.array([8, 16, 36, 59, 103, 190, 148, 260])
plt.title("不同星级的学校个数")
plt.rcParams["font.sans-serif"] = ["SimHei"] # 解决中文显示问题
plt.bar(x, y)
plt.show()
- 水平柱形图
python
运行
import matplotlib.pyplot as plt
import numpy as np
x = np.array(["8星", "7星", "6星", "5星", "4星", "3星", "2星", "1星"])
y = np.array([8, 16, 36, 59, 103, 190, 148, 260])
plt.title("不同星级的学校个数")
plt.rcParams["font.sans-serif"] = ["SimHei"]
plt.barh(x, y)
plt.show()
(二)饼图可视化不同星级学校占比
python
运行
import matplotlib.pyplot as plt
import numpy as np
y = np.array([1, 2, 4.5, 7.2, 12.5, 23.1, 18, 31.7]) # 各星级学校占比(%)
plt.pie(y, labels=["8星", "7星", "6星", "5星", "4星", "3星", "2星", "1星"])
plt.title("不同星级的学校个数占比")
plt.rcParams["font.sans-serif"] = ["SimHei"]
plt.show()
五、总结
今天的学习通过爬虫技术获取了中国大学排名数据,展示了从网页请求、数据解析到存储的完整爬虫流程;随后利用 pandas 进行数据预处理,解决了数据缺失问题;最后通过 matplotlib 绘制柱形图和饼图,直观呈现了不同星级学校的数量及占比分布。整个过程体现了爬虫技术在数据获取中的作用,以及数据分析与可视化在数据解读中的价值,为后续基于该数据的深入研究奠定了基础。