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()
来解决这个问题,但如果我能理解发生了什么以及如何理解,我会更加放心一个额外的字符会对文档产生如此破坏性的影响。
编辑。 使用 detwingle
或 ftfy
等工具不再有效。这是一个替代测试用例,具有正确的编码,在我的机器上没有被 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'
希望对您有所帮助
已编辑。 我正在使用 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()
来解决这个问题,但如果我能理解发生了什么以及如何理解,我会更加放心一个额外的字符会对文档产生如此破坏性的影响。
编辑。 使用 detwingle
或 ftfy
等工具不再有效。这是一个替代测试用例,具有正确的编码,在我的机器上没有被 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'
希望对您有所帮助