使用非utf-8编码在Python中解析XML

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用非utf-8编码在Python中解析XML相关的知识,希望对你有一定的参考价值。

有关如何在python中解析xml的任何线索,其中包含:encoding ='Windows-1255'?当XML头中的“encoding”标记不是“utf-8”或“ASCII”时,至少lxml.etree解析器甚至不会查看该字符串。

运行以下代码失败:

ValueError:不支持带编码声明的Unicode字符串。请使用字节输入或XML片段而不声明。

from lxml import etree

parser = etree.XMLParser(encoding='utf-8')

def convert_xml_to_utf8(xml_str):
    tree = etree.fromstring(xml_str, parser=parser)
    if tree.docinfo.encoding == 'utf-8':
        # already in correct encoding, abort
        return xml_str
    decoded_str = xml_str.decode(tree.docinfo.encoding)
    utf8_encoded_str = decoded_str.encode('utf-8')
    tree = etree.fromstring(utf8_encoded_str)
    tree.docinfo.encoding = 'utf-8'
    return etree.tostring(tree, pretty_print = True, xml_declaration = True, encoding='UTF-8', standalone="yes")


data = '''<?xml version='1.0' encoding='Windows-1255'?><rss version="2.0"><channel ><title ><![CDATA[ynet - חדשות]]></title></channel></rss>'''
print(convert_xml_to_utf8(data))
答案

data是一个unicode str。错误是说不支持包含encoding="..."声明的这样的东西,因为据说str已经从其编码中解码,因此它也含有编码声明是模糊/无意义的。它告诉你使用bytes代替,例如data = b'<...>'。据推测,您应该以二进制模式打开文件,从那里读取数据并让etree处理encoding="...",而不是在代码中使用字符串文字,这进一步使编码情况复杂化。

它很简单:

from xml.etree import ElementTree

#        open in binary mode ↓
with open('/tmp/test.xml', 'rb') as f:
    e = ElementTree.fromstring(f.read())

Etvoilà,e包含您的解析文件,编码已经(大概)由etree根据文件的内部encoding="..."标头正确解释。

ElementTree实际上有一个快捷方法:

e = ElementTree.parse('/tmp/test.xml')

以上是关于使用非utf-8编码在Python中解析XML的主要内容,如果未能解决你的问题,请参考以下文章

python解析xml,包含中文,gb2312编码。修改xml后重新写入xml有些内容怎么变了? 我的步骤如下:

XML 解析 - PHP 编码

UTF-8编码的xml文件带头部信息,用XmlDocument解析出错问题

使用 Java 和 UTF-8 编码生成有效的 XML

解析xml文档出现的问题

Python爬虫:BeautifulSoup库