如何用Python抓取高尔夫排行榜表格中特定td标签的球员最终杆数
解决ESPN高尔夫排行榜最终杆数抓取问题
问题背景
我是Python新手,想要抓取ESPN高尔夫排行榜(链接:https://www.espn.com/golf/leaderboard/_/tournamentId/401465506)中每位球员的最终杆数(示例中的-19)。目前已成功获取球员姓名,但因表格中存在多个class为Table__TD的td标签,无法提取目标td的内容。
尝试的代码如下:
from bs4 import BeautifulSoup import requests html_text = requests.get('https://www.espn.com/golf/leaderboard/_/tournamentId/401465506').text soup = BeautifulSoup(html_text, 'lxml') golfers = soup.find_all('tr', class_ = 'PlayerRow__Overview PlayerRow__Overview--expandable Table__TR Table__even') for golfer in golfers: golfer_name = golfer.a.text golfer_score = golfer.td.text print(f'{golfer_name} final score {golfer_score}')
运行后出现报错:
Traceback (most recent call last): File "C:\Users\mikef\AppData\Local\Temp\tempCodeRunnerFile.python", line 10, in <module> golfer_score = golfer.td = 'Table__TD'.text AttributeError: 'str' object has no attribute 'text' [Done] exited with code=1 in 0.559 seconds
注释掉golfer_score相关代码后,可正常获取所有球员姓名,现寻求正确提取球员最终杆数的方法。
错误分析
- 报错里的
golfer_score = golfer.td = 'Table__TD'.text是明显语法错误,你大概率是想定位class为Table__TD的标签,但写错了逻辑,直接对字符串调用.text导致报错。 - 即便没有语法错误,
golfer.td只会返回该行第一个td标签,而最终杆数并不在这个位置,自然拿不到目标数据。
解决方案
观察页面HTML结构,最终杆数所在的td带有Table__TD--number的额外class,也可以通过该行td的固定索引定位,两种方法如下:
方法1:通过特定class定位(更可靠)
from bs4 import BeautifulSoup import requests html_text = requests.get('https://www.espn.com/golf/leaderboard/_/tournamentId/401465506').text soup = BeautifulSoup(html_text, 'lxml') golfers = soup.find_all('tr', class_='PlayerRow__Overview PlayerRow__Overview--expandable Table__TR Table__even') for golfer in golfers: golfer_name = golfer.a.text # 定位带有Table__TD--number的td,对应最终杆数 golfer_score = golfer.find('td', class_='Table__TD Table__TD--number').text.strip() print(f'{golfer_name} final score: {golfer_score}')
方法2:通过索引定位
如果页面class有变动,可通过该行td的索引获取(最终杆数在第6个td,索引为5):
from bs4 import BeautifulSoup import requests html_text = requests.get('https://www.espn.com/golf/leaderboard/_/tournamentId/401465506').text soup = BeautifulSoup(html_text, 'lxml') golfers = soup.find_all('tr', class_='PlayerRow__Overview PlayerRow__Overview--expandable Table__TR Table__even') for golfer in golfers: golfer_name = golfer.a.text # 获取该行所有td标签,提取对应索引的内容 tds = golfer.find_all('td', class_='Table__TD') if len(tds) >= 6: golfer_score = tds[5].text.strip() print(f'{golfer_name} final score: {golfer_score}')
说明
.strip()用于去除杆数字符串前后的空白,保证输出整洁。- 方法1语义性更强,页面结构小幅度变动时更不容易失效;方法2需要确认索引准确性,页面更新后可能需要调整。
内容的提问来源于stack exchange,提问作者Mike Dietrich
相关产品推荐
相关产品推荐

