Python进阶:高效爬取NBA选秀体测数据

花韻仙語
发布: 2025-11-01 13:42:00
原创
259人浏览过

python进阶:高效爬取nba选秀体测数据

本教程旨在解决从NBA官网动态页面爬取选秀体测数据时遇到的挑战。针对传统HTML解析工具难以获取JavaScript动态加载内容的问题,文章将深入探讨如何通过分析网络请求,直接调用NBA官方API接口来获取结构化的JSON数据,并利用`pandas`库将其高效转换为易于处理的数据帧,从而实现稳定且高效的数据采集。

1. 动态网页爬取的挑战与传统方法的局限

在尝试从如NBA官网这类现代网站上爬取数据时,开发者经常会遇到一个常见问题:即使页面在浏览器中正常显示表格数据,使用requests和BeautifulSoup等工具直接请求页面HTML内容时,却无法找到目标数据。这通常是因为这些数据并非直接嵌入在初始HTML中,而是通过JavaScript在页面加载完成后异步从后端API获取并渲染到页面上的。

例如,对于NBA选秀体测数据页面(https://www.nba.com/stats/draft/combine-anthro),如果直接使用BeautifulSoup去查找<table>标签,很可能一无所获。这是因为页面上的数据表格是在浏览器端执行JavaScript代码后,通过AJAX请求从一个独立的API接口获取JSON数据,然后动态构建出来的。

2. 解决方案:识别并调用后端API

要解决这类问题,最有效的方法是绕过前端渲染过程,直接与后端数据源进行交互。这通常涉及到以下步骤:

立即学习Python免费学习笔记(深入)”;

  1. 检查网络请求: 使用浏览器开发者工具(通常按F12打开),切换到“Network”(网络)选项卡。刷新页面,观察在数据加载过程中发出的XHR/Fetch请求。
  2. 定位数据接口: 筛选这些请求,查找返回JSON数据且包含目标数据的请求。这些请求的URL通常会包含“stats”、“api”等关键词。
  3. 分析请求参数与响应结构: 仔细查看该请求的URL、请求方法(GET/POST)、请求头(Headers)和请求体(Payload/Params)。同时,分析其JSON响应的结构,以了解数据是如何组织的。

对于NBA选秀体测数据,通过开发者工具分析发现,页面数据实际上来源于一个名为draftcombineplayeranthro的API接口。

3. 实现数据爬取

一旦确定了API接口及其调用方式,我们就可以使用Python的requests库来模拟浏览器请求,直接获取JSON数据。

3.1 导入所需库

首先,我们需要导入requests库来发送HTTP请求,以及pandas库来处理和组织获取到的数据。

易企秀
易企秀

易企秀,一体化创意设计营销平台。超100万模板1键套用3分钟制作,随时随地完成创意设计营销。

易企秀44
查看详情 易企秀
import requests
import pandas as pd
登录后复制

3.2 定义API接口与请求参数

NBA的统计API通常需要特定的参数来过滤数据,例如LeagueID和SeasonYear。同时,为了模拟真实浏览器行为,避免被服务器识别为爬虫并拒绝访问,我们还需要设置一些HTTP请求头,如Referer和User-Agent。

# API接口URL
url = "https://stats.nba.com/stats/draftcombineplayeranthro"

# 请求参数,用于指定联赛ID和赛季年份
# LeagueID: "00" 通常代表NBA
# SeasonYear: 例如 "2022-23" 表示2022-2023赛季
payload = {
    "LeagueID": "00",
    "SeasonYear": "2022-23" # 根据需要修改赛季年份
}

# 请求头,模拟浏览器行为
headers = {
    "Referer": "https://www.nba.com/", # 模拟请求来源
    "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" # 模拟用户代理
}
登录后复制

注意: User-Agent字符串应尽可能使用最新的浏览器版本,可以从你的浏览器开发者工具中复制。

3.3 发送请求并解析JSON数据

使用requests.get()方法发送GET请求,并通过params参数传递payload,通过headers参数传递headers。API返回的数据是JSON格式,可以直接通过.json()方法解析为Python字典。

# 发送GET请求并获取JSON响应
response = requests.get(url, params=payload, headers=headers)
response.raise_for_status() # 检查请求是否成功(状态码200)
data = response.json()
登录后复制

3.4 将JSON数据转换为DataFrame

NBA统计API的JSON响应通常包含一个resultSets列表,其中每个元素代表一个数据集。每个数据集又包含headers(列名)和rowSet(数据行)。我们可以利用这些信息,方便地将数据转换为pandas.DataFrame。

# 从JSON数据中提取列名和数据行
# resultSets[0]通常是第一个(或唯一)数据集
columns = data["resultSets"][0]["headers"]
rows = data["resultSets"][0]["rowSet"]

# 创建DataFrame
df = pd.DataFrame(rows, columns=columns)
登录后复制

3.5 完整代码示例

import requests
import pandas as pd

def get_nba_combine_anthro_data(season_year="2022-23"):
    """
    从NBA官方API获取指定赛季的选秀体测数据。

    Args:
        season_year (str): 赛季年份,例如 "2022-23"。

    Returns:
        pd.DataFrame: 包含选秀体测数据的DataFrame。
                      如果获取失败,则返回None。
    """
    url = "https://stats.nba.com/stats/draftcombineplayeranthro"

    payload = {
        "LeagueID": "00",
        "SeasonYear": season_year
    }

    # 推荐使用最新的User-Agent字符串
    headers = {
        "Referer": "https://www.nba.com/",
        "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:
        response = requests.get(url, params=payload, headers=headers, timeout=10)
        response.raise_for_status() # 如果状态码不是200,则抛出HTTPError异常
        data = response.json()

        columns = data["resultSets"][0]["headers"]
        rows = data["resultSets"][0]["rowSet"]

        df = pd.DataFrame(rows, columns=columns)
        return df
    except requests.exceptions.RequestException as e:
        print(f"请求失败: {e}")
        return None
    except KeyError as e:
        print(f"JSON解析错误,可能API响应结构发生变化: {e}")
        return None

# 调用函数获取数据
nba_combine_df = get_nba_combine_anthro_data(season_year="2022-23")

if nba_combine_df is not None:
    print("成功获取NBA选秀体测数据:")
    print(nba_combine_df.head())
    print(f"\n数据总行数: {len(nba_combine_df)}")
    print(f"数据总列数: {len(nba_combine_df.columns)}")
登录后复制

3.6 示例输出

运行上述代码,你将得到一个包含NBA选秀体测数据的pandas.DataFrame,其部分内容如下所示:

成功获取NBA选秀体测数据:
   TEMP_PLAYER_ID  PLAYER_ID FIRST_NAME  ... BODY_FAT_PCT HAND_LENGTH HAND_WIDTH
0         1630534    1630534      Ochai  ...         5.40        8.75       9.50
1         1631116    1631116    Patrick  ...         8.90        8.75       9.50
2         1631094    1631094      Paolo  ...          NaN         NaN        NaN
3         1631109    1631109       Mark  ...         5.40        9.00       9.75
4         1630592    1630592      Jalen  ...          NaN         NaN        NaN

[5 rows x 18 columns]

数据总行数: 83
数据总列数: 18
登录后复制

4. 注意事项与总结

  • API稳定性: 官方API接口的URL、参数和JSON响应结构可能会随时间变化。如果代码突然失效,请重新检查NBA官网的网络请求,以获取最新的API信息。
  • 请求频率与限制: 频繁或高速的请求可能会触发网站的反爬机制,导致IP被封禁。在实际应用中,应设置合理的请求间隔(例如使用time.sleep()),并考虑使用代理IP池。
  • User-Agent: 保持User-Agent字符串更新,以模拟最新的浏览器行为,有助于降低被识别为爬虫的风险。
  • 错误处理: 在实际项目中,应加入更完善的错误处理机制,例如对网络请求失败、JSON解析异常等情况进行捕获和处理。
  • 道德与法律: 在进行网络爬取时,务必遵守网站的服务条款(Terms of Service)和当地的法律法规。仅获取公开数据,不进行恶意攻击或滥用资源。

通过直接调用后端API,我们能够高效且稳定地获取NBA选秀体测数据,避免了前端JavaScript渲染带来的复杂性。这种方法不仅适用于NBA官网,也适用于许多其他采用动态加载内容的网站,是现代网络数据采集的重要技术之一。

以上就是Python进阶:高效爬取NBA选秀体测数据的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号