You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何抓取NBA网站中无ID且难以解析的表格数据?

NBA官网球员数据表格抓取问题

尝试抓取NBA官网的球员传统数据表格时,使用BeautifulSoup和pd.read_html()均无法正确解析提取目标表格。

所用代码

stars_url ="https://www.nba.com/stats/players/traditional?Season={}&dir=A&sort=NBA_FANTASY_PTS"

season = '2010-11' 
url = stars_url.format(season) 
data = requests.get(url)
soup = BeautifulSoup(data.text) 
stat = soup.select("table", class_ ="Crom_table__p1iZz")


import pandas as pd 
from io import StringIO 
stat_tr = pd.read_html(StringIO(str(stat)), encoding='utf-8') 
stat_tr

错误结果

返回的是日历表格而非目标球员数据:

[   Sun  Mon  Tues  Wed  Thurs  Fri  Sat
0   31    1     2    3      4    5    6
1    7    8     9   10     11   12   13
2   14   15    16   17     18   19   20
3   21   22    23   24     25   26   27
4   28   29    30   31      1    2    3,
Sun  Mon  Tues  Wed  Thurs  Fri  Sat
0   31    1     2    3      4    5    6
1    7    8     9   10     11   12   13
2   14   15    16   17     18   19   20
3   21   22    23   24     25   26   27
4   28   29    30   31      1    2    3]

已尝试的方法

  • 使用soup.find_all()查找目标表格
  • 使用pd.read_html(data.text, match="Crom_table__p1iZz")匹配表格类名

*注:目标表格(players_traditional_stats)没有id,增加了查找难度。


解决方法

1. 问题根源

NBA官网的球员数据表格是通过JavaScript动态加载的,直接用requests.get()获取的HTML里根本没有目标表格的内容,你拿到的日历表格是页面里其他静态渲染的元素。

2. 可行方案

方案一:模拟浏览器加载(用Selenium)

直接用Selenium模拟浏览器打开页面,等待JS加载完成后再提取表格:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import pandas as pd

stars_url ="https://www.nba.com/stats/players/traditional?Season={}&dir=A&sort=NBA_FANTASY_PTS"
season = '2010-11' 
url = stars_url.format(season) 

# 初始化浏览器(需提前下载对应版本的chromedriver)
driver = webdriver.Chrome()
driver.get(url)

# 等待目标表格加载完成
wait = WebDriverWait(driver, 10)
table = wait.until(EC.presence_of_element_located((By.CLASS_NAME, "Crom_table__p1iZz")))

# 提取表格HTML并转成DataFrame
html = table.get_attribute('outerHTML')
df = pd.read_html(html)[0]

# 关闭浏览器
driver.quit()

print(df.head())

方案二:调用NBA官方API

NBA Stats页面的数据其实是通过API接口获取的,直接调用接口更高效,不需要解析HTML:

import requests
import pandas as pd

season = '2010-11'
url = f"https://stats.nba.com/stats/leaguedashplayerstats?College=&Conference=&Country=&DateFrom=&DateTo=&Division=&DraftPick=&DraftYear=&GameScope=&GameSegment=&Height=&LastNGames=0&LeagueID=00&Location=&MeasureType=Base&Month=0&OpponentTeamID=0&Outcome=&PORound=0&PaceAdjust=N&PerMode=PerGame&Period=0&PlayerExperience=&PlayerPosition=&PlusMinus=N&Rank=N&Season={season}&SeasonSegment=&SeasonType=Regular+Season&ShotClockRange=&StarterBench=&TeamID=0&TwoWay=0&VsConference=&VsDivision=&Weight="

# 请求头要模拟浏览器,否则会被拦截
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36",
    "Referer": "https://www.nba.com/stats"
}

response = requests.get(url, headers=headers)
data = response.json()

# 提取数据和列名
columns = [col['name'] for col in data['resultSets'][0]['headers']]
rows = data['resultSets'][0]['rowSet']
df = pd.DataFrame(rows, columns=columns)

print(df[['PLAYER_NAME', 'PTS', 'REB', 'AST']].head())

3. 为什么之前的方法无效

  • 直接requests.get()只能拿到页面的静态HTML,动态加载的表格内容还没被渲染出来,所以你找不到目标表格,反而匹配到了页面里的日历表格。
  • pd.read_html()会解析HTML里所有的<table>标签,当目标表格不存在时,就会返回其他无关的表格。

内容的提问来源于stack exchange,提问作者KIZ-MAN

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 21:23:10