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

时间:2015-06-29 22:46:10

标签: python beautifulsoup lxml python-unicode

已编辑。我正在使用带有lxml的BeautifulSoup来解析来自外部源的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>

但是,如果我改变一件事并删除一个字符&#39; X&#39;:

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>"

如上所述发生同样的问题。 谁能解释一下?

1 个答案:

答案 0 :(得分:1)

这可能不是最佳解决方案,但这是我在抓取非ascii网站时所做的。它每次都很完美。

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

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

所以打印/保存或解析你刚才做的任何非ascii字符,

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

希望有所帮助