- Beautiful Soup教程
- Beautiful Soup - 主页
- Beautiful Soup - 概述
- Beautiful Soup - 安装
- Beautiful Soup - 汤页面
- Beautiful Soup - 各种物体
- Beautiful Soup - 按标签导航
- Beautiful Soup - 寻找树
- Beautiful Soup-修改树
- Beautiful Soup - 编码
- Beautiful Soup - 美丽的物体
- 仅解析文档的部分
- Beautiful Soup - 故障排除
- Beautiful Soup有用的资源
- Beautiful Soup - 快速指南
- Beautiful Soup - 有用的资源
- Beautiful Soup - 讨论
Beautiful Soup - 故障排除
错误处理
BeautifulSoup 中需要处理的错误主要有两种。这两个错误不是来自您的脚本,而是来自代码片段的结构,因为 BeautifulSoup API 会引发错误。
两个主要错误如下 -
属性错误
这是由于点符号找不到当前 HTML 标记的同级标记而导致的。例如,您可能遇到过这个错误,因为缺少“锚标记”,cost-key在遍历时会抛出错误并需要锚标记。
按键错误
如果缺少所需的 HTML 标记属性,则会出现此错误。例如,如果我们在代码片段中没有 data-pid 属性,则 pid 键将抛出键错误。
为了在解析结果时避免上述两个列出的错误,该结果将被绕过,以确保格式错误的代码片段不会插入到数据库中 -
except(AttributeError, KeyError) as er: pass
诊断()
每当我们发现难以理解 BeautifulSoup 对文档或 HTML 的作用时,只需将其传递给diagnose() 函数即可。将文档文件传递给diagnose()函数时,我们可以展示不同解析器的列表如何处理文档。
下面是一个演示diagnose()函数使用的例子 -
from bs4.diagnose import diagnose with open("20 Books.html",encoding="utf8") as fp: data = fp.read() diagnose(data)
输出
解析错误
解析错误主要有两种类型。当您将文档提供给 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。
另一种常见的意外Behave是您在文档中找不到已知的标签。但是,当您运行 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。
Unicode编码错误
让我们看看下面的代码段 -
soup = BeautifulSoup(response, "html.parser") print (soup)
输出
UnicodeEncodeError: 'charmap' codec can't encode character '\u011f'
上述问题可能主要有两种情况造成。您可能正在尝试打印控制台不知道如何显示的 unicode 字符。其次,您尝试写入文件,但传入了默认编码不支持的 Unicode 字符。
解决上述问题的一种方法是在制作汤之前对响应文本/字符进行编码以获得所需的结果,如下所示 -
responseTxt = response.text.encode('UTF-8')
密钥错误:[attr]
这是由于当相关标签未定义 attr 属性时访问 tag['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 元素列表。
您需要做的就是迭代列表并从这些元素中捕获数据。