Beautiful Soup 报告 UnicodeEncodeError "ordinal not in range(128)

5 投票
2 回答
945 浏览
提问于 2025-04-17 08:59

我正在尝试解析从网上下载的各种文档,没错,我对这些文档的内容没有控制权。

因为Beautiful Soup在处理糟糕的标记时不会出错...,我想知道为什么当文档的某一部分格式不正确时,它会出现问题,是否有办法让它继续解析文档中下一个可以读取的部分,而不受这个错误的影响。

错误发生的那一行是第三行:

from BeautifulSoup  import BeautifulSoup as doc_parser
reader = open(options.input_file, "rb")
doc = doc_parser(reader)

命令行的完整输出是:

Traceback (most recent call last):
  File "./grablinks", line 101, in <module>
    sys.exit(main())
  File "./grablinks", line 88, in main
    links = grab_links(options)
  File "./grablinks", line 36, in grab_links
    doc = doc_parser(reader)
  File "/usr/local/lib/python2.7/dist-packages/BeautifulSoup.py", line 1519, in __init__
    BeautifulStoneSoup.__init__(self, *args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/BeautifulSoup.py", line 1144, in __init__
    self._feed(isHTML=isHTML)
  File "/usr/local/lib/python2.7/dist-packages/BeautifulSoup.py", line 1186, in _feed
    SGMLParser.feed(self, markup)
  File "/usr/lib/python2.7/sgmllib.py", line 104, in feed
    self.goahead(0)
  File "/usr/lib/python2.7/sgmllib.py", line 143, in goahead
        k = self.parse_endtag(i)
  File "/usr/lib/python2.7/sgmllib.py", line 320, in parse_endtag
    self.finish_endtag(tag)
  File "/usr/lib/python2.7/sgmllib.py", line 358, in finish_endtag
    method = getattr(self, 'end_' + tag)
UnicodeEncodeError: 'ascii' codec can't encode characters in position 15-16: ordinal not in range(128)

2 个回答

0

如果你在使用 Python 3.0 之前的版本时,输入中包含非 ASCII 字符,就会出现这个问题。

当你尝试对一个包含字符值大于 128 的字符串使用 str(...) 时,就会引发这个异常(错误)。这些字符包括 ANSI 和 Unicode 字符。

这个错误可能是因为 getattr 尝试在一个 Unicode 字符串上使用 str,它“认为”这样做是安全的,因为在 Python 3.0 之前,标识符(变量名等)不能包含 Unicode 字符。

检查一下你的 HTML 中是否有 Unicode 字符。尝试替换或编码这些字符,如果还是不行,请告诉我们。

2

嗯,如果你有一些名字里包含非ASCII字符的元素(比如<café>),那就会出问题。这其实并不是‘糟糕的标记’,在XML中也是如此……

这是sgmllib中的一个bug,而BeautifulSoup正是用这个库的。它试图找到和标签同名的自定义方法,但在Python 2中,方法名是字节字符串,所以即使是去找一个包含非ASCII字符的方法,也永远找不到,这就出错了。

你可以通过修改sgmllib中的第259和371行,把except AttributeError:改成except AttributeError, UnicodeError:来临时解决这个问题,但这并不是一个好的解决方案。想要覆盖这个方法的其他部分也不简单。

你想解析的是什么呢?BeautifulStoneSoup的实用性一直都值得怀疑——XML没有HTML那样复杂的解析问题,所以一般来说,损坏的XML就不算XML。因此,你通常应该使用一个普通的XML解析器(比如标准的DOM或etree)。如果是解析一般的HTML,现如今html5lib是更好的选择。

撰写回答