使用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
相关产品推荐
相关产品推荐

