爬虫与数据分析

要爬取数据,首先得了解网页的 "构造"。通过查看网页源代码发现,大学排名数据整齐地放在一个 HTML 表格中(标签为<table>),表格的每行对应一所大学(标签为<tr>),每行中的单元格(标签为<td>)则分别存储名次、学校名称、总分等信息。

简单来说,网页中的数据就像一个 Excel 表格,我们只需要找到对应的 "行" 和 "列",就能精准提取信息。

代码实现:三步搞定数据爬取

我们用 Python 的requests库获取网页内容,BeautifulSoup库解析网页结构,再用csv库保存数据,核心代码分为三个函数:获取网页内容(get_html 函数):发送网络请求,获取网页的 HTML 文本,并处理可能出现的请求错误(如网络超时)。python运行

复制代码
import requests
def get_html(url, time=3):
    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)
  • 解析数据(parser 函数) :用BeautifulSoup解析 HTML,定位到表格的每行数据,提取学校名称、总分等关键信息,存入列表。python运行

    复制代码
    from bs4 import BeautifulSoup
    def parser(html):
        soup = BeautifulSoup(html, "lxml")  # 解析网页
        out_list = []
        # 遍历表格的每一行(tr标签)
        for row in soup.select("table>tbody>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
  • 保存数据(save_csv 函数):将解析后的列表数据写入 CSV 文件,方便后续用 Excel 或 Python 读取。python运行

    复制代码
    import csv
    def save_csv(item, path):
        with open(path, "wt", newline="", encoding="utf-8") as f:
            csv_write = csv.writer(f)
            csv_write.writerows(item)  # 写入多行数据

运行结果

调用上述函数后,我们成功生成了school.csv文件,打开后可以看到清晰的数据:

复制代码
学校名称,总分,全国排名,星级排名,办学层次
北京大学,100,1,8★,世界一流大学
清华大学,99.81,2,8★,世界一流大学
浙江大学,80.72,4,8★,世界一流大学
...

爬取的数据往往不完美,比如school.csv中的 "总分" 列存在空值(部分学校未显示分数)。我们用pandas库处理这些问题,常用 4 种方法:

直接删除含空值的行

如果空值较少,且删除后不影响整体分析,可以直接去掉包含空字段的行:

python运行

复制代码
import pandas as pd
df = pd.read_csv("school.csv")
new_df = df.dropna()  # 删除含空值的行
print(new_df.to_string())

python运行

复制代码
df = pd.read_csv("school.csv")
df.fillna("暂无分数信息", inplace=True)  # 替换空值
print(df.to_string())

用均值填充空值如果 "总分" 是数值型数据,可用列的平均值(均值)填补空值,让数据更符合整体趋势:

python运行

复制代码
df = pd.read_csv("school.csv")
x = df["总分"].mean()  # 计算总分的均值
df["总分"].fillna(x, inplace=True)  # 用均值替换空值
print(df.to_string())

用中位数填充空值均值容易受极端值影响(比如某所学校总分特别高),此时可用中位数(将数据排序后中间的数值)更稳健地填补空值:

python运行

复制代码
df = pd.read_csv("school.csv")
x = df["总分"].median()  # 计算总分的中位数
df["总分"].fillna(x, inplace=True)  # 用中位数替换空值
print(df.to_string())

1. 柱形图:对比不同星级学校的数量

星级排名反映了学校的综合实力,我们用柱形图展示各星级学校的数量:

  • 8 星学校:8 所
  • 7 星学校:16 所
  • 6 星学校:36 所
  • 5 星学校:59 所
  • 4 星学校:103 所
  • 3 星学校:190 所
  • 2 星学校:148 所
  • 1 星学校:260 所

代码实现(用matplotlib库):

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.barh(x,y)为水平柱形图)
plt.show()

1 星和 3 星学校数量最多,8 星学校最少,符合 "顶尖学校稀缺" 的常识。

2. 饼图:展示各星级学校的占比

如果想知道各星级学校在总量中的占比(如 8 星学校约占 1%,1 星学校约占 31.7%),饼图是更好的选择:代码实现:

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])
labels = ["8星", "7星", "6星", "5星", "4星", "3星", "2星", "1星"]

# 绘图
plt.pie(y, labels=labels)  # 饼图
plt.title("不同星级的学校个数占比")
plt.rcParams["font.sans-serif"] = ["SimHei"]
plt.show()

饼图直观呈现:1 星学校占比超过三成,3 星学校占比约两成,两者合计超过一半,反映了 "普通学校占多数" 的分布特征。今天的学习就到这里了,下期再见。

相关推荐
小关会打代码3 分钟前
关于Pycharm中在运行出现语法错误:Non-UTF-8 code starting with
ide·python·pycharm
用户3721574261353 分钟前
Python 高效将 PDF 转换为 HTML 的实用指南
python
深栈5 分钟前
机器学习:编码方式
人工智能·python·机器学习·编码
yzx9910139 分钟前
Django 搭配数据库开发智慧园区系统全攻略
python·django·数据库开发
PixelMind17 分钟前
【LLIE技术专题】 SCI代码讲解
图像处理·python·低照度图像增强·llie
泰迪智能科技20 分钟前
分享“泰迪杯”数据挖掘挑战赛全新升级——赛题精准对标,搭建 “白名单” 赛事进阶通道
人工智能·数学建模·数据挖掘
67X26 分钟前
数据仓库与数据挖掘课程设计
数据仓库·数据挖掘
天才测试猿40 分钟前
Python常用自动化测试框架—Pytest详解
自动化测试·软件测试·python·测试工具·职场和发展·测试用例·pytest
胡耀超1 小时前
2、CPU深度解析:从微架构到性能优化
python·性能优化·架构·arm·cpu·x86·多核心
en-route1 小时前
使用 Flask 构建 Web 应用:静态页面与动态 API 访问
前端·python·flask