You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

基于球员姓名关联Basketball Reference多表数据的Python实现求助

实现从Basketball Reference匹配球员花名册与统计数据的方案建议

嘿,看起来你已经迈出了很棒的第一步——成功抓取到凯尔特人队的花名册了!接下来要把totals表的球员数据匹配到对应花名册行的末尾,核心是找到球员的唯一标识来关联两个表格,我给你梳理下具体的实现方向和代码修改建议:

核心思路

Basketball Reference的表格里,每个球员都有一个唯一的data-append-csv属性值(比如球员Kyrie Irving的这个值是irvinky01),这个值是跨表格匹配的关键——不管是roster表还是totals表,同一个球员的这个值是一致的,我们可以用它来建立映射关系。

具体实现步骤

  • 步骤1:提取花名册时,同时获取球员的唯一标识和基本信息
    不要只提取td的文本,还要把每个球员行的data-append-csv属性值存下来,这个是后续匹配的钥匙。
  • 步骤2:提取totals表格的球员统计数据
    同样从totals表中提取每个球员的data-append-csv值,以及对应的得分、篮板、助攻等统计字段,把这些数据存成一个字典,键是data-append-csv值,值是统计数据的列表。
  • 步骤3:关联两个表格的数据
    遍历花名册的每一行,用该行的data-append-csv值去字典里查找对应的统计数据,找到后就追加到该行的末尾;如果找不到(比如某些球员没有totals数据),可以用空值填充。
  • 步骤4:输出整理好的数据
    把合并后的结果转换成DataFrame或者直接写入CSV文件,方便后续使用。

修改后的代码示例

from selenium import webdriver
from bs4 import BeautifulSoup
import pandas as pd

# 直接使用你指定的2019赛季凯尔特人页面
team_url = "https://www.basketball-reference.com/teams/BOS/2019.html"

driver = webdriver.Chrome()
driver.get(team_url)
soup = BeautifulSoup(driver.page_source, 'lxml')
driver.quit()  # 用完浏览器记得关闭

# 1. 提取花名册数据(包含唯一标识)
roster_data = []
roster_table = soup.find('table', id='roster')
# 获取花名册表头
roster_headers = [th.text for th in roster_table.select('thead tr th')]
# 遍历每一行球员数据
for row in roster_table.select('tr')[1:]:
    # 获取球员的唯一标识
    player_slug = row.get('data-append-csv')
    # 获取该行的文本数据
    row_text = [td.text for td in row.select("td")]
    # 把唯一标识插入到行数据的开头
    row_text.insert(0, player_slug)
    roster_data.append(row_text)
# 给表头添加唯一标识的列名
roster_headers.insert(0, 'Player_Slug')

# 2. 提取totals表格的统计数据,建立slug到数据的映射
totals_map = {}
totals_table = soup.find('table', id='totals')
# 获取totals的表头(跳过第一列的Rk)
totals_headers = [th.text for th in totals_table.select('thead tr th')[1:]]
for row in totals_table.select('tr')[1:]:
    # 跳过空行和汇总行
    if not row.get('data-append-csv'):
        continue
    player_slug = row.get('data-append-csv')
    # 获取统计数据,跳过第一列的Rk
    stats = [td.text for td in row.select("td")[1:]]
    totals_map[player_slug] = stats

# 3. 合并两个表格的数据
merged_data = []
# 合并表头:花名册表头 + totals表头
merged_headers = roster_headers + totals_headers
for row in roster_data:
    player_slug = row[0]
    # 查找对应的统计数据,找不到就用空值填充
    player_stats = totals_map.get(player_slug, [''] * len(totals_headers))
    # 合并行数据
    merged_row = row + player_stats
    merged_data.append(merged_row)

# 4. 转换成DataFrame并输出
df = pd.DataFrame(merged_data, columns=merged_headers)
print(df.head())
# 保存成CSV文件
df.to_csv('bos_2019_roster_with_stats.csv', index=False)

额外注意事项

  • 表格里可能存在空行或者汇总行(比如totals表底部的球队总计行),所以要判断row.get('data-append-csv')是否存在,避免程序报错。
  • 如果遇到球员没有totals数据(比如只在花名册但没出场),用空值填充是比较稳妥的方式,不会打断程序运行。
  • 如果你不需要Selenium,其实可以直接用requests库获取页面内容,因为Basketball Reference的静态页面不需要渲染,这样运行效率会更高(把Selenium的部分换成requests.get(team_url)再解析即可)。

内容的提问来源于stack exchange,提问作者Shaun

火山引擎 最新活动