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

使用Beautiful Soup爬取NBA数据:解决CSV单元格合并问题

解决ESPN NBA球员数据CSV导出字段拆分问题

问题根源

你的代码有两个核心问题导致所有统计值挤在一个单元格:

  • split_list = [elem.split() for elem in all_splits]把每个<td>的文本拆成了子列表,最终statslist里存的是嵌套列表,和姓名、PER值打包后,整段列表会被当作CSV的单个单元格内容。
  • 没有从URL中提取Year字段,也没给DataFrame设置明确列名,导致输出格式不符合预期。

修正后的代码

import requests
from bs4 import BeautifulSoup
from concurrent.futures import ThreadPoolExecutor
import pandas as pd
import re

# 示例数据,替换为你的实际列表
names_list = ["Tim Duncan", "Kobe Bryant"]
pers = [24.8, 25.9]
statsurls = [
    "https://insider.espn.com/nba/player/splits/_/id/532/type/nba/year/2003/category/perGame",
    "https://insider.espn.com/nba/player/splits/_/id/977/type/nba/year/2003/category/perGame"
]

def GetStats(statsurl):
    # 从URL提取年份
    year_match = re.search(r'/year/(\d{4})/', statsurl)
    year = year_match.group(1) if year_match else "Unknown"
    
    statsreq = requests.get(statsurl)
    statssoup = BeautifulSoup(statsreq.text, 'lxml')
    # 定位表格tbody
    tbody = statssoup.select_one('main#fittPageContainer div.Table__Scroller > table > tbody')
    if not tbody:
        return [year] + ["N/A"]*10  # 无数据时返回占位值
    
    # 获取"all splits"行(第2行,索引1)的所有td文本
    all_splits_row = tbody.find_all('tr')[1]
    all_splits_values = [td.text.strip() for td in all_splits_row.find_all('td')]
    
    # 返回年份+统计值的扁平化列表
    return [year] + all_splits_values

# 用线程池执行并收集结果
with ThreadPoolExecutor() as executor:
    stats_results = [future.result() for future in executor.map(GetStats, statsurls)]

# 构建完整数据集:姓名、PER、年份、统计字段
full_data = []
for name, per, stats in zip(names_list, pers, stats_results):
    full_data.append([name] + [per] + stats)

# 设置CSV列名(根据ESPN页面实际字段调整顺序)
column_names = [
    "Name", "PER #", "Year", "GP", "Min", "FG", "FGA", "FG%", "3P", "3PA", "3P%",
    "FT", "FTA", "FT%", "ORB", "DRB", "TRB", "AST", "STL", "BLK", "TOV", "PF", "PTS"
]

# 创建DataFrame并导出CSV
df = pd.DataFrame(full_data, columns=column_names)
df.to_csv('player_stats.csv', index=False, encoding='utf-8-sig')

关键改动说明

  • 用正则从URL提取年份,补充Year字段。
  • 直接返回扁平化统计值列表,避免嵌套结构导致的单元格合并。
  • 使用executor.map更简洁地获取线程执行结果,替代submit+手动收集的繁琐写法。
  • 设置明确列名,确保每个字段对应独立单元格。
  • 增加空数据容错处理,避免爬取失败导致程序崩溃。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 10:20:47