如何在Python中将HTML非ASCII数据编码为UTF-8

如何在Python中将HTML非ASCII数据编码为UTF-8,python,unicode,utf-8,Python,Unicode,Utf 8,我试着这么做,发现了以下错误: >>> import re >>> x = 'Ingl\xeas' >>> x 'Ingl\xeas' >>> print x Ingl�s >>> x.decode('utf8') Traceback (most recent call last): File "<stdin>", line 1, in <modul

我试着这么做,发现了以下错误:

>>> import re  
>>> x = 'Ingl\xeas'  
>>> x  
'Ingl\xeas'  
>>> print x  
Ingl�s  
>>> x.decode('utf8')  
Traceback (most recent call last):  
    File "<stdin>", line 1, in <module>  
    File "/usr/lib/python2.6/encodings/utf_8.py", line 16, in decode  
        return codecs.utf_8_decode(input, errors, True)  
UnicodeDecodeError: 'utf8' codec can't decode bytes in position 4-5: unexpected end of data  
>>> x.decode('utf8', 'ignore')  
u'Ingl'  
>>> x.decode('utf8', 'replace')  
u'Ingl\ufffd'  
>>> print x.decode('utf8', 'replace')  
Ingl�  
>>> print x.decode('utf8', 'xmlcharrefreplace')  
Traceback (most recent call last):  
    File "<stdin>", line 1, in <module>  
    File "/usr/lib/python2.6/encodings/utf_8.py", line 16, in decode  
        return codecs.utf_8_decode(input, errors, True)  
TypeError: don't know how to handle UnicodeDecodeError in error callback  

欢迎提供任何帮助。

在解码之前,您需要知道输入数据是如何编码的。在一些尝试中,您试图从UTF-8对其进行解码,但是Python抛出了一个异常,因为输入不是有效的UTF-8。看起来可能是拉丁语-1。这对我很有用:

>>> x = 'Ingl\xeas'
>>> print x.decode('latin1')
Inglês
您提到“非ASCII HTML”。如果您正在编写web服务器脚本,并且正在从HTTP请求获取数据,则应检查内容类型头。在理想情况下,它会告诉您客户机对数据使用的编码。请记住,客户机可能工作不正常

希望有帮助

Ingl\xeas
不是UTF-8,而是(可能)Windows-1252-或latin1编码。所以你首先需要解码它。只有这样,您才能将其编码为UTF-8

因此:

>>> x = 'Ingl\xeas'
>>> print x.decode("cp1252")
Inglês
同样地

 >>> x.decode("cp1252").encode("UTF-8")
 'Ingl\xc3\xaas'
这是正确的UTF-8表示形式

顺便说一下,在Python3中,您可以(至少在Windows下的交互式控制台中)简单地键入

>>> x = 'Ingl\xeas'
>>> print (x)
Inglês
由于Python 3字符串始终是Unicode字符串(不计算
字节
对象)。

一些观察结果:

(1)
latin1
将解码任何8位字节而不会引发异常。只有在用尽所有其他可能性后,才使用拉丁文1。用于帮助确定特定文件、网页或XML流的编码格式

(2) 基于非常有限的证据(一个字符)的可能备选方案:

(3) U+0080到U+009F(包括)的范围被分配给“C1控制字符”,unicode.org之外的人都不知道这些字符有什么用途。无论您使用什么编码(即使是UTF-8),在对unicode进行无一例外的解码之后,您还没有走出困境。检查该范围内的字符。如果发现任何错误,则表明数据已损坏,或者编码选择不正确

def check_for_c1_control_characters(unicode_obj):
    return any('\u0080' <= c <= '\u009F' for c in unicode_obj)
def check_查找控制字符(unicode_obj):

返回任何(“\u0080”Python3有两种字符串类型,就像Python2.3的
str
是2的
unicode
做了一些小的修改。3的
bytes
是2的
str
做了一些小的修改。@Daniel:不在交互式shell中。对我来说是这样的。我想这取决于安装是如何设置的?我得到:unicode错误:“ascii”编解码器无法对位置4中的字符“\xea”进行编码:序号不在范围内(128)哦,这可能与本地环境有关。我在Windows上,因此交互式shell的编码为Windows-1252。在Linux下,它可能是UTF-8。将编辑我的帖子。
>>> import unicodedata as ucd
>>> for codepage in range(1250, 1259):
...    try:
...        uc = "\xea".decode(str(codepage))
...    except UnicodeDecodeError:
...        pass
...    if uc == u'\xea': print codepage, ucd.name(uc)
...
1252 LATIN SMALL LETTER E WITH CIRCUMFLEX
1254 LATIN SMALL LETTER E WITH CIRCUMFLEX
1256 LATIN SMALL LETTER E WITH CIRCUMFLEX
1258 LATIN SMALL LETTER E WITH CIRCUMFLEX
>>>
def check_for_c1_control_characters(unicode_obj):
    return any('\u0080' <= c <= '\u009F' for c in unicode_obj)