访问存在的<a>元素.text属性时出现NoneType错误排查
问题描述
我正在使用BeautifulSoup爬取维基百科页面《List of military engagements during the Russian invasion of Ukraine》中的第一个wikitable,以获取全部57场战役的名称。为抓取第一列所有<a>元素的文本(战役名称),编写了如下代码:
import requests from bs4 import BeautifulSoup url = 'https://en.wikipedia.org/wiki/List_of_military_engagements_during_the_Russian_invasion_of_Ukraine' page = requests.get(url) soup = BeautifulSoup(page.text, 'lxml') table = soup.find('table') rows = table.find_all('tr') battlenames = [] for row in rows: # Find the first <td> element within the row td_element = row.find('td') if td_element: # Find the first <a> element within the <td> element battlename = td_element.find('a') cleanname = battlename.text battlenames.append(cleanname) for name in battlenames: print(name)
运行后出现如下错误:
AttributeError Traceback (most recent call last) Cell In[6], line 18 15 if td_element: 16 # Find the first <a> element within the <td> element 17 battlename = td_element.find('a') ---> 18 cleanname = battlename.text 19 battlenames.append(cleanname) 21 for name in battlenames: AttributeError: 'NoneType' object has no attribute 'text'
我认为每一行<tr>的第一个<td>元素中都包含带有战役名称的<a>元素,不应触发NoneType错误,请问问题出在哪里?
问题原因与解决方案
核心原因
你用soup.find('table')获取的是页面第一个表格——维基百科页面顶部的信息框(Infobox),而非目标的战役列表wikitable。信息框的部分<td>单元格内没有<a>标签,导致td_element.find('a')返回None,调用.text时触发错误。
修正方案
- 精准定位目标表格:通过
class_='wikitable'筛选出战役列表的表格,因为目标表格带有wikitable类属性。 - 增加空值判断:即使定位到正确表格,也建议对
battlename是否为None做判断,避免意外报错。
修正后的代码:
import requests from bs4 import BeautifulSoup url = 'https://en.wikipedia.org/wiki/List_of_military_engagements_during_the_Russian_invasion_of_Ukraine' page = requests.get(url) soup = BeautifulSoup(page.text, 'lxml') # 定位带有wikitable类的表格 table = soup.find('table', class_='wikitable') rows = table.find_all('tr') battlenames = [] for row in rows: td_element = row.find('td') if td_element: battlename = td_element.find('a') # 增加判断,避免battlename为None时出错 if battlename: cleanname = battlename.text.strip() battlenames.append(cleanname) for name in battlenames: print(name)
补充说明
如果目标页面存在多个wikitable,可以用soup.find_all('table', class_='wikitable')[0]明确获取第一个,确保拿到的是战役列表表格。
内容的提问来源于stack exchange,提问作者Kai Garcia
相关产品推荐
相关产品推荐

