首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Python 数据分析前置:BeautifulSoup 爬取 NBA 数据源

Python 数据分析前置:BeautifulSoup 爬取 NBA 数据源

原创
作者头像
小白学大数据
发布2026-03-03 16:46:55
发布2026-03-03 16:46:55
30
举报

一、前言:为什么需要爬取 NBA 数据源?

对于 NBA 数据分析爱好者而言,数据源的获取主要有两种方式:一是借助 NBA 官方提供的 API 接口,二是通过网页爬取的方式获取公开数据。前者虽然数据精准、格式规范,但存在接口调用限制、部分数据收费等问题,对于非专业开发者不够友好;后者则针对公开的 NBA 静态网页(如 NBA 中文官网、篮球数据网站等),通过解析网页结构提取数据,门槛低、自由度高,适合入门学习者。

BeautifulSoup 是 Python 中用于解析 HTML 和 XML 文档的第三方库,与 Requests 库配合使用,能够快速抓取网页内容并提取关键数据,无需复杂的正则表达式,上手难度极低。本文将以 NBA 中文官网的球员数据为爬取目标,带领读者掌握 BeautifulSoup 的核心用法,同时完成 NBA 数据源的采集,为后续的得分分析、球员效率分析、球队战绩分析等工作提供数据支撑。

本文爬取的核心目标的是:NBA 常规赛球员的基础数据(姓名、位置、出场次数、得分、篮板、助攻等),爬取对象为 NBA 中文官网的公开数据页面,全程采用 Python 3.x 环境,核心依赖库为 Requests(请求网页)和 BeautifulSoup4(解析网页)。

二、环境搭建:必备工具与依赖库安装

在开始爬取工作前,需要先完成 Python 环境的搭建以及相关依赖库的安装。本文采用 Python 3.8 版本(兼容 3.6 及以上所有版本),读者可根据自身电脑系统(Windows、Mac、Linux)下载对应的 Python 安装包,安装过程中勾选“Add Python to PATH”,确保后续能够正常使用命令行调用 Python。

2.1 核心依赖库说明

本次爬取工作需要用到两个核心依赖库,分别是:

1. Requests:用于向目标网页发送 HTTP 请求,获取网页的 HTML 源代码。它是 Python 中最常用的网络请求库,语法简洁,支持 GET、POST 等多种请求方式,能够轻松应对静态网页的请求需求。

2. BeautifulSoup4(简称 bs4):用于解析 Requests 获取到的 HTML 源代码,提取网页中的目标数据。它能够将复杂的 HTML 文档转化为树形结构,提供简单易用的 API,让开发者能够快速定位并提取所需内容,无需编写复杂的正则表达式。

三、网页分析:定位 NBA 数据所在位置

网页爬取的核心是“找到数据所在的 HTML 位置”,在编写代码前,需要先分析目标网页的结构,确定我们需要的 NBA 球员数据藏在 HTML 代码的哪个部分。本文的爬取目标是 NBA 中文官网的“球员数据”页面,具体步骤如下:

3.1 确定目标网页地址

打开浏览器(推荐 Chrome 或 Edge),访问 NBA 中文官网的球员数据页面,本次爬取的页面地址为:https://china.nba.com/stats/players/。该页面展示了 NBA 所有球员的常规赛基础数据,支持按得分、篮板等维度排序,数据公开且结构清晰,适合作为爬取目标。

3.2 分析网页结构,定位数据位置

在目标网页上,右键点击“检查”(或按 F12 键),打开浏览器的开发者工具,切换到“Elements”(元素)选项卡,即可查看网页的 HTML 源代码。我们需要找到包含球员数据的 HTML 标签,具体操作如下:

1. 在开发者工具中,点击左上角的“选择元素”按钮(箭头图标),然后点击网页中的球员数据表格,即可在 HTML 源代码中定位到表格对应的标签。

2. 观察 HTML 结构,发现球员数据全部放在一个 <table> 标签中,该标签的 class 属性为“stats-table”,这是我们定位表格的核心标识。

3. 表格内部,<thead> 标签包含表头信息(姓名、位置、出场次数、得分等),<tbody> 标签包含所有球员的具体数据,每一行球员数据对应一个 <tr> 标签,每一个单元格对应一个 <td> 标签。

通过以上分析,我们可以确定:只需定位到 class 为“stats-table”的 <table> 标签,然后提取 <tbody> 标签下的所有 <tr> 标签,再逐一解析每个 <tr> 标签下的 <td> 标签内容,即可获取所有球员的基础数据。

需要注意的是,部分网页会采用动态加载技术(如 JavaScript 渲染),但本次爬取的 NBA 中文官网球员数据页面为静态网页,HTML 源代码中直接包含所有球员数据,无需处理动态加载问题,适合入门练习。

四、代码实现:完整爬取流程与解析

结合前面的环境搭建和网页分析,我们接下来编写完整的爬取代码,全程分为 5 个步骤:发送 HTTP 请求获取网页源代码、使用 BeautifulSoup 解析网页、提取表头信息、提取球员数据、保存数据到本地(CSV 格式,方便后续数据分析)。

4.1 完整代码(可直接复制运行)

代码语言:javascript
复制
# 导入所需依赖库
import requests
from bs4 import BeautifulSoup
import csv

# 1. 定义目标网页地址(NBA 中文官网球员数据页面)
url = "https://china.nba.com/stats/players/"

# 2. 发送 HTTP GET 请求,获取网页 HTML 源代码
# 添加请求头,模拟浏览器访问,避免被反爬
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"
}

try:
    # 发送 GET 请求
    response = requests.get(url, headers=headers)
    # 验证请求是否成功(状态码 200 表示成功)
    response.raise_for_status()
    # 设置编码格式,避免中文乱码
    response.encoding = response.apparent_encoding
    # 获取 HTML 源代码
    html = response.text
    print("网页请求成功,已获取 HTML 源代码")
except Exception as e:
    print(f"网页请求失败,错误信息:{e}")
    exit()  # 请求失败则退出程序

# 3. 使用 BeautifulSoup 解析 HTML 源代码
# 指定解析器为 lxml(需要安装 lxml 库,若未安装,执行 pip install lxml)
soup = BeautifulSoup(html, "lxml")

# 4. 提取目标数据(表头 + 球员数据)
# 4.1 提取表头信息
table = soup.find("table", class_="stats-table")  # 定位球员数据表格
thead = table.find("thead")  # 找到表头所在标签
th_list = thead.find_all("th")  # 提取所有表头单元格
headers = []
for th in th_list:
    # 提取表头文本,去除空格和换行符
    header = th.get_text(strip=True)
    headers.append(header)
print("表头信息:", headers)

# 4.2 提取球员数据
tbody = table.find("tbody")  # 找到球员数据所在标签
tr_list = tbody.find_all("tr")  # 提取所有球员数据行
player_data_list = []  # 存储所有球员数据

for tr in tr_list:
    td_list = tr.find_all("td")  # 提取当前行的所有单元格
    player_data = []
    for td in td_list:
        # 提取单元格文本,去除空格和换行符
        data = td.get_text(strip=True)
        player_data.append(data)
    player_data_list.append(player_data)
print(f"共爬取到 {len(player_data_list)} 名球员的数据")
print("前 5 名球员数据:", player_data_list[:5])

# 5. 保存数据到本地 CSV 文件
# CSV 文件路径(可自行修改,如:D:/NBA球员数据.csv)
csv_path = "NBA球员数据.csv"

try:
    with open(csv_path, "w", newline="", encoding="utf-8-sig") as f:
        # 创建 CSV 写入器
        writer = csv.writer(f)
        # 写入表头
        writer.writerow(headers)
        # 写入所有球员数据
        writer.writerows(player_data_list)
    print(f"数据保存成功,文件路径:{csv_path}")
except Exception as e:
    print(f"数据保存失败,错误信息:{e}")

4.2 代码分步解析

步骤 1:导入依赖库

代码开头导入了三个所需库:requests 用于发送网络请求,BeautifulSoup 用于解析 HTML,csv 用于将数据保存为 CSV 格式。其中,csv 是 Python 内置库,无需额外安装,直接导入即可使用。

步骤 2:发送 HTTP 请求,获取网页源代码

首先定义目标网页的 URL,然后添加请求头(User-Agent),模拟浏览器访问——这是避免被网站反爬的基础操作。很多网站会检测请求的 User-Agent,若发现是爬虫程序(默认 User-Agent 为 Python-requests),会拒绝提供数据,因此需要设置浏览器的 User-Agent。

使用 try-except 语句包裹请求代码,用于捕获请求过程中可能出现的错误(如网络中断、网页无法访问等),提高代码的健壮性。请求成功后,设置编码格式为 response.apparent_encoding,避免中文乱码,然后获取网页的 HTML 源代码。

步骤 3:使用 BeautifulSoup 解析 HTML

将获取到的 HTML 源代码传入 BeautifulSoup,指定解析器为 lxml——lxml 解析器解析速度快、兼容性好,是 BeautifulSoup 最常用的解析器。若未安装 lxml 库,执行 pip install lxml 即可。

解析后得到 soup 对象,通过 soup 对象的 find() 和 find_all() 方法,即可定位到目标 HTML 标签,提取所需数据。

步骤 4:提取表头和球员数据

1. 提取表头:通过 soup.find("table", class_="stats-table") 定位到球员数据表格(class 为 stats-table),然后找到 <thead> 标签,提取所有 <th> 标签的文本,作为 CSV 文件的表头。

2. 提取球员数据:找到 <tbody> 标签,提取所有 <tr> 标签(每一行对应一名球员),然后逐一解析每个 <tr> 标签下的 <td> 标签文本,将每一名球员的数据存储为列表,最终汇总到 player_data_list 中。

代码中使用 get_text(strip=True) 方法提取标签文本,strip=True 表示去除文本前后的空格和换行符,确保数据的整洁性。

步骤 5:保存数据到 CSV 文件

使用 Python 内置的 csv 库,将表头和球员数据写入 CSV 文件。open() 函数中,encoding="utf-8-sig" 用于避免中文乱码(Windows 系统默认编码为 GBK,utf-8-sig 可兼容 Windows 和 Mac 系统),newline="" 用于避免 CSV 文件中出现多余的空行。

保存成功后,可在当前代码所在目录下找到“NBA球员数据.csv”文件,打开后即可看到所有爬取的球员数据,后续可直接用于 Python 数据分析(如使用 Pandas 读取 CSV 文件)。

五、常见问题与解决方案

在实际爬取过程中,可能会遇到一些问题,导致爬取失败或数据异常,以下是几种常见问题及对应的解决方案,帮助读者顺利完成爬取工作。

5.1 问题 1:网页请求失败,提示“403 Forbidden”

原因:网站检测到请求不是来自浏览器,拒绝提供数据(反爬机制)。

解决方案:完善请求头,除了 User-Agent,还可以添加 Referer(表示请求来源),代理IP,修改后的 headers 如下:

代码语言:javascript
复制
import requests

# 1. 定义代理信息
proxyHost = "www.16yun.cn"
proxyPort = "5445"
proxyUser = "16QMSOML"
proxyPass = "280651"

# 2. 构建代理配置(包含认证信息)
proxies = {
    "http": f"http://{proxyUser}:{proxyPass}@{proxyHost}:{proxyPort}",
    "https": f"https://{proxyUser}:{proxyPass}@{proxyHost}:{proxyPort}"
}

# 3. 请求头配置
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",
    "Referer": "https://china.nba.com/"
}

# 4. 发送带代理的请求示例(以NBA中国官网为例)
if __name__ == "__main__":
    try:
        # 目标请求地址
        url = "https://china.nba.com/"
        
        # 发送GET请求,传入headers和proxies参数
        response = requests.get(
            url=url,
            headers=headers,
            proxies=proxies,
            timeout=10  # 设置超时时间,避免请求卡死
        )
        
        # 验证请求是否成功
        response.raise_for_status()  # 抛出HTTP状态码异常(如404/500等)
        print(f"请求成功,状态码:{response.status_code}")
        print(f"响应内容长度:{len(response.text)} 字符")
        
    except requests.exceptions.RequestException as e:
        print(f"请求失败:{e}")

5.2 问题 2:解析网页时,提示“AttributeError: 'NoneType' object has no attribute 'find'”

原因:未找到目标 HTML 标签(如 table 标签),可能是网页结构发生变化,或请求头未设置导致获取的 HTML 源代码异常。

解决方案:1. 重新检查网页结构,确认目标标签的 class 或 id 是否发生变化;2. 验证请求是否成功,打印 html 变量查看获取的 HTML 源代码是否正常;3. 更换解析器(如将 lxml 改为 html.parser)。

5.3 问题 3:数据保存后,中文乱码

原因:编码格式设置错误,Windows 系统默认编码为 GBK,若使用 utf-8 编码保存,可能会出现乱码。

解决方案:将 open() 函数中的 encoding 设置为 utf-8-sig,而非 utf-8,utf-8-sig 会自动添加 BOM 头,兼容 Windows 系统的 Excel 打开。

5.4 问题 4:爬取的数据不完整

原因:NBA 官网的球员数据页面可能分页展示,本文代码仅爬取第一页数据,若需要获取所有球员数据,需处理分页逻辑。

解决方案:分析分页 URL 的规律,通过循环遍历所有分页,逐一爬取每一页的数据,然后汇总保存。例如,分页 URL 可能为 https://china.nba.com/stats/players/?page=1、https://china.nba.com/stats/players/?page=2,可通过循环改变 page 参数的值,实现多页爬取。

六、延伸:爬取数据后的数据分析方向

本文完成的 NBA 数据源爬取,是数据分析的前置步骤,获取数据后,可借助 Python 的 Pandas、Matplotlib、Seaborn 等库,开展以下数据分析工作:

1. 球员得分分析:统计球员的场均得分、总得分,筛选得分榜前 10 名球员,绘制得分分布直方图,分析联盟得分整体情况。

2. 球员效率分析:结合篮板、助攻、抢断、盖帽等数据,计算球员的效率值(PER),评估球员的综合表现。

3. 球队数据汇总:按球队分组,统计各球队的场均得分、场均篮板、胜率等数据,分析不同球队的实力差异。

4. 数据可视化:通过 Matplotlib 绘制折线图、柱状图、热力图等,直观展示球员数据之间的关联(如得分与篮板的相关性)。

例如,使用 Pandas 读取 CSV 文件的代码如下:

代码语言:javascript
复制
import pandas as pd

# 读取 CSV 文件
df = pd.read_csv("NBA球员数据.csv")

# 查看数据前 5 行
print(df.head())

# 查看数据基本信息(缺失值、数据类型等)
print(df.info())

# 统计场均得分前 10 名球员
top10_score = df.sort_values(by="场均得分", ascending=False).head(10)
print("场均得分前 10 名:")
print(top10_score[["姓名", "球队", "场均得分"]])

七、总结

本文以“Python 数据分析前置”为核心,完整讲解了使用 BeautifulSoup 爬取 NBA 数据源的全流程,从环境搭建、网页分析,到代码实现、问题排查,每一步都兼顾专业性和实用性,适合 Python 入门学习者上手练习。

通过本文的学习,读者不仅能够掌握 BeautifulSoup 和 Requests 库的核心用法,成功获取 NBA 球员数据,更能理解“数据爬取是数据分析的基础”这一核心逻辑——只有掌握了数据源的获取方法,才能后续开展更深入的数据分析工作。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、前言:为什么需要爬取 NBA 数据源?
  • 二、环境搭建:必备工具与依赖库安装
    • 2.1 核心依赖库说明
  • 三、网页分析:定位 NBA 数据所在位置
    • 3.1 确定目标网页地址
    • 3.2 分析网页结构,定位数据位置
  • 四、代码实现:完整爬取流程与解析
    • 4.1 完整代码(可直接复制运行)
    • 4.2 代码分步解析
      • 步骤 1:导入依赖库
      • 步骤 2:发送 HTTP 请求,获取网页源代码
      • 步骤 3:使用 BeautifulSoup 解析 HTML
      • 步骤 4:提取表头和球员数据
      • 步骤 5:保存数据到 CSV 文件
  • 五、常见问题与解决方案
    • 5.1 问题 1:网页请求失败,提示“403 Forbidden”
    • 5.2 问题 2:解析网页时,提示“AttributeError: 'NoneType' object has no attribute 'find'”
    • 5.3 问题 3:数据保存后,中文乱码
    • 5.4 问题 4:爬取的数据不完整
  • 六、延伸:爬取数据后的数据分析方向
  • 七、总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档