BeautifulSoup爬取fbref英超球员数据报NoneType无text属性问题求解
报错核心原因
- 触发
AttributeError: 'NoneType' object has no attribute 'text'的本质是代码执行row.find("td", {"data-stat": f})时未匹配到目标标签,返回None对象后强行调用.text属性导致异常。 - 涉及的6个失效字段(player、nationality、position、squad、age、birth_year)匹配失败的具体原因:
player字段的标签类型不匹配:目标网站的球员名单元格默认使用th标签(也就是代码中用来筛选有效行的那个带scope="row"属性的标签),标签自带data-stat="player"属性,但代码统一只查找td标签,必然无法匹配到该字段。- 其余5个字段匹配失败的常见诱因:
- 表格定位错位:代码通过
soup.findAll("tbody")取固定索引[1]获取球员表格,若页面加载了其他隐藏的统计模块(如分组排名、位置统计等非目标表格),固定索引会取错对象,自然找不到对应data-stat的单元格。 - 反爬拦截:无请求头的裸
requests请求会被目标网站识别,返回简化版页面结构,前几个文本类字段的标签会被替换为动态加载占位符,导致标签匹配失效。
- 表格定位错位:代码通过
可直接落地的修复方案
- 修正
player字段的获取逻辑,单独处理th标签的内容,不要统一从td中查找:for f in features_wanted_player: # 单独匹配player字段的th标签 if f == "player": cell = row.find("th", {"data-stat": "player"}) else: cell = row.find("td", {"data-stat": f}) - 增加空值保护,从根源上避免NoneType报错:拿到匹配结果后先判断是否为空,不存在对应单元格时直接赋值空值,不要强行调用
.text:# 替换原直接取text的逻辑 if not cell: text = "" else: a = cell.text.strip().encode() text = a.decode("utf-8") - 调整表格定位逻辑,不用固定索引取表格,改成按表格唯一ID精准匹配目标球员统计表,避免因页面结构变化取错对象:
# 替换原all_tables的固定索引取值逻辑 player_table = soup.find("table", {"id": "stats_squads_standard_for"}).find("tbody") - 给请求增加模拟浏览器的请求头,避免被反爬策略返回简化页面:
headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" } res = requests.get(url, headers=headers) - 优化空值填充规则:原逻辑对所有空值统一填充为'0'的规则不适用于文本类字段,会污染球员信息,可调整为文本类字段用空值占位,数值类字段填充0:
if text == '': text = np.nan if f in ["player","nationality","position","squad","age","birth_year"] else '0'
内容的提问来源于stack exchange,提问作者Rose
相关产品推荐
相关产品推荐

