BeautifulSoup爬取NFL数据时报'NoneType' object has no attribute 'text'如何解决
问题原因
报错是因为row.find('td', class_ = 'left')返回了None值,你直接对None调用.text属性就触发了该错误,核心有两个触发场景:
- 目标表格的
<tbody>内插入了多条重复表头行、间隔分隔行,这类行没有class为left的<td>元素,查找后直接返回空 - 部分数据行的class为
left的<td>并不是姓名列,匹配规则不精准也可能返回空
此外你的代码还存在潜在问题:用固定下标取class=right的列,一旦页面列顺序调整就会触发索引越界报错。
解决方法
优化元素匹配规则,增加非空校验,优先用页面自带的data-stat属性定位列(该属性是网站给每列固定打的标识,比class和下标稳定得多),修改后的可运行代码如下:
import requests from bs4 import BeautifulSoup url = "https://www.pro-football-reference.com/years/2021/passing.htm" r = requests.get(url) soup = BeautifulSoup(r.text, 'html.parser') league_table = soup.find('table', class_ = 'per_match_toggle sortable stats_table') # 遍历tbody下的所有行 for tbody in league_table.find_all('tbody'): rows = tbody.find_all('tr') for row in rows: # 用data-stat属性精准定位姓名列 name_td = row.find('td', {'data-stat': 'player'}) # 非空校验,找不到直接跳过当前行 if not name_td: continue name = name_td.text.strip() # 同样用data-stat定位码数和达阵列 yards_td = row.find('td', {'data-stat': 'yds'}) td_td = row.find('td', {'data-stat': 'pass_td'}) if not yards_td or not td_td: continue yards = yards_td.text touchdowns = td_td.text print(f"Name {name} Yards {yards} Touchdowns {touchdowns}")
修改说明
- 替换了原来的class匹配、下标取列的方式,用页面固定的
data-stat属性匹配目标列,匹配精准度大幅提升,不会因为页面列顺序调整失效 - 所有取值操作前都增加了非空校验,遇到无效的间隔行、表头行直接跳过,不会触发属性调用报错
- 用f-string优化了输出格式,可读性更高
内容的提问来源于stack exchange,提问作者Tajae Anderson
相关产品推荐
相关产品推荐

