BeautifulSoup 和 XML 无法解析完整的 unicode 字符串

BeautifulSoup with XML fails to parse full unicode strings

已编辑。 我正在使用 BeautifulSoup 和 lxml 来解析来自外部源的 XML 文档。奇怪的是,在某些文档上,解析器似乎在文本中间放弃并缩短了文档。

我已将其精简为一个精确的测试用例:

from bs4 import BeautifulSoup
xml = "<ElementA><ElementB>Before bad character XX\n\x80 BAD\nAfter bad character</ElementB><ElementC>In element C</ElementC></ElementA>"
soup = BeautifulSoup(xml,"xml")
soup

给出错误的输出:

<?xml version="1.0" encoding="utf-8"?>
<ElementA><ElementB/></ElementA>

但是如果我只改变一件事并删除一个字符 'X':

from bs4 import BeautifulSoup
xml = "<ElementA><ElementB>Before bad character X\n\x80 BAD\nAfter bad character</ElementB><ElementC>In element C</ElementC></ElementA>"
soup = BeautifulSoup(xml,"xml")
soup

然后我得到更完整的输出:

<?xml version="1.0" encoding="utf-8"?>
<ElementA><ElementB>Before bad character X
 BAD
After bad character</ElementB><ElementC>In element C</ElementC></ElementA>

这是怎么回事?我在 Python 3.4.3、OSX.

上使用 BeautifulSoup 4.3.2 和 LXML 3.4.4

到目前为止,我已经设法通过在解析之前将 XML 字符串传递给 UnicodeDammit.detwingle() 来解决这个问题,但如果我能理解发生了什么以及如何理解,我会更加放心一个额外的字符会对文档产生如此破坏性的影响。

编辑。 使用 detwingleftfy 等工具不再有效。这是一个替代测试用例,具有正确的编码,在我的机器上没有被 bs4 / lxml 正确解析:

xml = "<ElementA><ElementB>Before bad character XX\n• BAD\nAfter bad character</ElementB><ElementC>In element C</ElementC></ElementA>"

出现与上述相同的问题。 谁能解释一下?

这可能不是最好的解决方案,但这是我在抓取非 ASCII 网站时所做的。而且每次都完美无缺。

将默认编码更改为与网站相同。你的情况 utf-8

import sys
reload(sys)
sys.setdefaultencoding('utf-8')

所以 print/save 或解析任何非 ASCII 字符,

print 'non-ascii character'.encode('utf-8','ignore') # Replace your text or variable instead of 'non-ascii character'

希望对您有所帮助