Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/341.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 发生lxml LookupError。参数:(“未知编码:';b';utf-8-sig';';,)_Python_Xml_Parsing_Lxml - Fatal编程技术网

Python 发生lxml LookupError。参数:(“未知编码:';b';utf-8-sig';';,)

Python 发生lxml LookupError。参数:(“未知编码:';b';utf-8-sig';';,),python,xml,parsing,lxml,Python,Xml,Parsing,Lxml,当我使用python lxml库(最新版本)指定自己的编码时,我得到了一个LookupError 出现了LookupError。参数:(“未知编码:'b'utf-8-sig'”,) 由于某种原因,lxml不知道“utf-8-sig”,而它是python 3的标准编码。看 你知道如何解决这个问题吗?这是一个很好的解决方案,即使我不明白它为什么有效 长话短说,使用utf-8而不是utf-8-sig,即使存在utf-8编码的BOM,它也可以工作: >>> data = b'\xef\

当我使用python lxml库(最新版本)指定自己的编码时,我得到了一个LookupError

出现了LookupError。参数:(“未知编码:'b'utf-8-sig'”,)

由于某种原因,lxml不知道“utf-8-sig”,而它是python 3的标准编码。看

你知道如何解决这个问题吗?

这是一个很好的解决方案,即使我不明白它为什么有效 长话短说,使用
utf-8
而不是
utf-8-sig
,即使存在utf-8编码的BOM,它也可以工作:

>>> data = b'\xef\xbb\xbf<test/>'
>>> lxml.etree.parse(io.BytesIO(data), parser=lxml.etree.XMLParser(encoding='utf-8'))
<lxml.etree._ElementTree object at 0x7f3403e47730>
背景信息 lxml是libxml2库的包装器。因此,传递给
XMLParser
encoding
参数不是Python编码的名称,而是iconv编码名称。我必须深入研究才能弄清楚这一点,并且可以通过检查(例如,
OSF00010004
)来确认这一点,iconv在我的系统上支持这一点,但Python不支持这一点:

>>> lxml.etree.parse(io.BytesIO(b'\xef\xbb\xbf<test/>'), parser=lxml.etree.XMLParser(encoding='utf8', remove_blank_text=True))
Traceback (most recent call last):
  ...
lxml.etree.XMLSyntaxError: Start tag expected, '<' not found, line 1, column 1
>>> lxml.etree.parse(io.BytesIO(b'<test/>'), parser=lxml.etree.XMLParser(encoding='OSF00010004'))
<lxml.etree._ElementTree object at 0x7f8baa6adc30>
>>> b'<test/>'.decode('OSF00010004')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
LookupError: unknown encoding: OSF00010004
如上所述,这效率较低,因为在libxml2使用它之前,必须将其重新编码到UTF-8中

您还需要注意,如果XML包含像
这样的编码声明,这种方法将失败:

如果您处理的是来自第三方的XML,那么这可能会破坏交易

一个我确实理解的更好的解决方法 我们也可以自己去掉UTF-8编码的BOM表,因为它总是三个字节
\xef\xbb\xbf

遗憾的是,在类似文件的对象上执行此操作比在字符串上执行此操作要复杂得多,因为您无法提前读取。将文件包装在
io.BufferedReader
中可以使用
peek()
函数,但无法控制它返回的字节数

因此,安全的方法是首先将所有内容读入缓冲区:

response_bytes = response_bytes_io.read()
if response_bytes.startswith(b'\xef\xbb\xbf'):
    response_bytes = response_bytes[3:]
parser = etree.XMLParser(encoding='utf-8')
xml = etree.parse(source=io.BytesIO(response_bytes), parser=parser)

这比直接在流上操作效率低,因为解析延迟到读取整个响应为止,但它仍然比额外的解码和重新编码过程更有效。

我已经向lxml提出了一个问题:
response_string = response_bytes_io.read().decode('utf-8-sig')
xml = etree.fromstring(response_string)
ValueError: Unicode strings with encoding declaration are not supported.
Please use bytes input or XML fragments without declaration.
response_bytes = response_bytes_io.read()
if response_bytes.startswith(b'\xef\xbb\xbf'):
    response_bytes = response_bytes[3:]
parser = etree.XMLParser(encoding='utf-8')
xml = etree.parse(source=io.BytesIO(response_bytes), parser=parser)