使用requests和bs4爬取basketball-reference数据失败求助
排查Jimmy Butler赛季数据爬取失败的问题
以下是几个核心排查方向和解决办法:
1. 验证页面结构与选择器匹配度
- 打开目标球员页面,用浏览器开发者工具检查
per_game表格的结构:- 确认球员名字是否嵌套在
<a>标签中(比如<td><a>Jimmy Butler</a></td>),如果你的代码直接判断整行文本是否包含名字,可能因其他冗余文本导致匹配失败。 - 部分赛季行可能带有特定class(如
full_table),未筛选的话会混入汇总行或部分数据行,干扰匹配。
- 确认球员名字是否嵌套在
- 临时打印所有
tbody内的行文本,确认目标名字是否存在于返回的页面内容中。
2. 解决反爬拦截问题
basketball-reference会识别非浏览器请求,默认requests的请求头会被拦截,导致返回空页面或反爬提示。添加模拟浏览器的请求头:
import requests from bs4 import BeautifulSoup 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' } url = "目标球员的basketball-reference页面URL" response = requests.get(url, headers=headers) soup = BeautifulSoup(response.text, 'html.parser')
可以先打印response.text前500字符,确认返回的是正常页面内容。
3. 精准定位目标行与数据
不要用模糊匹配,直接通过data-stat属性定位名字列和数据列,确保精准匹配:
# 定位per_game表格的完整数据行 for row in soup.select('#per_game tbody tr.full_table'): # 找到名字对应的td标签 player_col = row.find('td', {'data-stat': 'player'}) if player_col and player_col.text.strip() == 'Jimmy Butler': # 提取2022-23赛季的指定数据 pts = row.find('td', {'data-stat': 'pts'}).text ast = row.find('td', {'data-stat': 'ast'}).text print(f"2022-23赛季数据: 得分(PTS)={pts}, 助攻(AST)={ast}") break else: print("Jimmy Butler's statistics not found.")
这种方式能避免文本干扰,直接定位目标球员的赛季数据行。
4. 排除动态加载可能性
虽然per_game表格通常是静态渲染,但如果上述方法都无效,可检查页面是否通过JS动态加载数据。这种情况下可以改用selenium渲染页面后再解析,但优先确认静态请求的有效性。
内容的提问来源于stack exchange,提问作者Nick R
相关产品推荐
相关产品推荐

