Beautiful Soup 故障排除

Beautiful Soup 故障排除

错误处理

BeautifulSoup需要处理的错误主要有两种。这两种错误不是来自你的脚本,而是来自代码片段的结构,因为BeautifulSoup API会抛出错误。

这两种主要的错误如下:

AttributeError

当点运算符在当前HTML标签中找不到兄弟标签时,会引发此错误。例如,你可能遇到了这个错误,因为缺少了“锚点标签”,cost-key在遍历时会引发错误,因为它需要一个锚点标签。

KeyError

如果需要的HTML标签属性缺失,会发生此错误。例如,如果片段中没有data-pid属性,pid键会引发键错误。

为了避免上述两种错误,在解析结果时,会绕过该结果以确保不会将格式不正确的片段插入数据库中。

except(AttributeError, KeyError) as er:
pass

diagnose()

每当我们在理解BeautifulSoup对我们的文档或HTML所做的操作方面遇到困难时,只需将其传递给测试()函数。通过将文档文件传递给测试()函数,我们可以展示不同解析器处理文档的列表。

以下是一个示例,演示了测试()函数的使用方法:

from bs4.diagnose import diagnose

with open("20 Books.html",encoding="utf8") as fp:
   data = fp.read()

diagnose(data)

输出

Beautiful Soup 故障排除

解析错误

有两种主要类型的解析错误。当您将文档输入到BeautifulSoup时,可能会出现类似HTMLParseError的异常。您也可能会得到一个意外的结果,其中BeautifulSoup的解析树与解析文档的预期结果看起来非常不同。

解析错误的原因都不是BeautifulSoup造成的,而是因为我们使用的外部解析器(html5lib,lxml),因为BeautifulSoup本身不包含任何解析器代码。解决上述解析错误的一种方法是使用另一个解析器。

from HTMLParser import HTMLParser

try:
   from HTMLParser import HTMLParseError
except ImportError, e:
   # From python 3.5, HTMLParseError is removed. Since it can never be
   # thrown in 3.5, we can just define our own class as a placeholder.
   class HTMLParseError(Exception):
      pass

Python内置的HTML解析器会导致两个最常见的解析错误,即HTMLParser.HTMLParserError: malformed start tag和HTMLParser.HTMLParserError: bad end tag,并且要解决这个问题,可以使用另一个主要解析器:lxml或html5lib。

另一种常见的意外行为类型是,你找不到你知道在文档中存在的标签。然而,当你运行find_all()返回[]或find()返回None时。

这可能是因为Python内置的HTML解析器有时会跳过它不理解的标签。

XML解析器错误

默认情况下,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字符。

解决上述问题的一种方法是在创建BeautifulSoup对象之前对响应文本/字符进行编码,以获得所需的结果,如下所示−

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 "tutorialspoint" in item['href']):
      (...)
   except KeyError:
      pass # or some other fallback action

AttributeError

您可能会遇到以下的属性错误−

AttributeError: 'list' object has no attribute 'find_all'

上述错误主要是因为您期望find_all()返回一个单独的标签或字符串。然而,soup.find_all返回一个Python元素的列表。

您只需要通过遍历列表并从这些元素中获取数据即可。

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程