为什么BeautifulSoup会抛出这个HTMLParseError?
我原以为BeautifulSoup可以处理格式不正确的文档,但当我把一个页面的源代码发给它时,出现了以下错误信息:
Traceback (most recent call last):
File "mx.py", line 7, in
s = BeautifulSoup(content)
File "build\bdist.win32\egg\BeautifulSoup.py", line 1499, in __init__
File "build\bdist.win32\egg\BeautifulSoup.py", line 1230, in __init__
File "build\bdist.win32\egg\BeautifulSoup.py", line 1263, in _feed
File "C:\Python26\lib\HTMLParser.py", line 108, in feed
self.goahead(0)
File "C:\Python26\lib\HTMLParser.py", line 150, in goahead
k = self.parse_endtag(i)
File "C:\Python26\lib\HTMLParser.py", line 314, in parse_endtag
self.error("bad end tag: %r" % (rawdata[i:j],))
File "C:\Python26\lib\HTMLParser.py", line 115, in error
raise HTMLParseError(message, self.getpos())
HTMLParser.HTMLParseError: bad end tag: u"", at line 258, column 34
难道它不能处理这种情况吗?如果可以的话,我该怎么做?如果不行,有没有其他模块可以处理格式不正确的文档呢?
补充一下:我用火狐浏览器把页面保存到本地,然后试着从文件内容创建一个soup对象。结果BeautifulSoup在这一步失败了。如果我直接从网站创建soup对象,那就没问题。这是导致soup出问题的文档。
3 个回答
根据我的经验,BeautifulSoup在处理错误方面不是特别宽容。我曾经为了写一个小脚本用过它,但遇到了一些问题。我觉得用正则表达式去掉标签有一点帮助,但最后我还是放弃了,转而用Ruby和Nokogiri来写这个脚本。
问题似乎出在第258行的这段代码:
contents = contents.replace(/</g, '<');
还有下一行的类似代码:
contents = contents.replace(/>/g, '>');
我建议直接用re.sub来替换掉所有出现的r"replace(/[<>]/"的地方,换成一些无害的内容,然后再把它传给BeautifulSoup……我觉得如果不使用BeautifulSoup,就像是把婴儿和洗澡水一起倒掉一样。
我用BeautifulSoup 3.0.7版本的时候一切都很好用。现在最新的是3.1.0,不过在BeautifulSoup的主页上有个提示,如果你遇到问题,可以试试3.0.7a版本。我之前也遇到过类似的问题,后来把版本降回去,问题就解决了;你也可以试试这个方法。
如果你想继续用现在的版本,我建议你把顶部那个大大的<script>
块去掉,因为错误就是在那部分出现的,而且用BeautifulSoup根本解析不了那部分内容。