在使用Beautiful Soup解析HTML/XML文档时,你可能会遇到错误,这些错误不是来自你的脚本,而是因为片段的结构问题导致BeautifulSoup API抛出了错误。
默认情况下,BeautifulSoup包将文档解析为HTML,但是使用beautifulsoup4处理不规范的XML非常方便。
要将文档解析为XML,你需要有lxml解析器,并且只需要将"xml"作为第二个参数传递给BeautifulSoup构造函数:
soup = BeautifulSoup(markup, "lxml-xml")
或者
soup = BeautifulSoup(markup, "xml")
一个常见的XML解析错误是:
AttributeError: 'NoneType' object has no attribute 'attrib'
这种情况可能会发生在使用find()
或findall()
函数时,某些元素缺失或未定义的情况下。
除了上述提到的解析错误外,你还可能会遇到其他解析问题,比如环境问题,你的脚本在一个操作系统下工作正常但在另一个操作系统下不工作,或者在一个虚拟环境中工作但在另一个虚拟环境中或非虚拟环境中不工作。这些问题可能是由于两个环境中有不同的解析库可用造成的。
建议了解或检查你在当前工作环境中的默认解析器。你可以检查当前工作环境中可用的默认解析器,或者显式地将所需的解析库作为第二个参数传递给BeautifulSoup构造函数。
由于HTML标签和属性不区分大小写,所有三个HTML解析器都会将标签和属性名称转换为小写。然而,如果你想保留混合大小写或大写的标签和属性,则最好将文档解析为XML。
UnicodeEncodeError
让我们来看下面的代码片段:
soup = BeautifulSoup(response, "html.parser")
print(soup)
输出
UnicodeEncodeError: 'charmap' codec can't encode character '\u011f'
上述问题可能是由两种情况引起的。你可能试图打印一个控制台不知道如何显示的Unicode字符。其次,你试图写入一个文件,并传入了一个默认编码不支持的Unicode字符。
解决上述问题的一种方法是在创建soup之前对响应文本/字符进行编码,以获得预期的结果,如下所示:
responseTxt = response.text.encode('UTF-8')
KeyError: [attr]
当你访问tag['attr']
而该标签没有定义attr
属性时,就会出现此错误。最常见的错误是:"KeyError: 'href'" 和 "KeyError: 'class'"。如果你不确定attr
是否已定义,请使用tag.get('attr')
。
for item in soup.fetch('a'):
try:
if (item['href'].startswith('/') or "yoagoa" in item['href']):
(...)
except KeyError:
pass
AttributeError
你可能会遇到如下形式的AttributeError
:
AttributeError: 'list' object has no attribute 'find_all'
上述错误主要是因为你期望find_all()
返回单个标签或字符串。然而,soup.find_all
返回的是一个Python元素列表。
你需要做的是遍历这个列表,并从这些元素中获取数据。
为了避免在解析结果时出现上述错误,可以通过以下方式跳过有问题的结果,以确保不正确的片段不会被插入数据库:
except (AttributeError, KeyError) as er:
pass