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

2024-06-09 17:11:59 发布

您现在位置:Python中文网/ 问答频道 /正文

我试着这么做,却发现了这个错误:

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

当我使用print语句时,我希望:

>>> print x  
u'Inglês'  

欢迎任何帮助。


Tags: inmoststdinlineutf8callutffile
3条回答
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表示。

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

>>> x = 'Ingl\xeas'
>>> print (x)
Inglês

因为Python 3字符串总是Unicode字符串(不包括bytes对象)。

一些观察:

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

(2)基于非常有限的证据(一个特征)的可能替代方案:

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

(3)U+0080到U+009F(包括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)

或者使用正则表达式,如this example中的“如何修复数据损坏的多种方法之一”。

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

>>> x = 'Ingl\xeas'
>>> print x.decode('latin1')
Inglês

你提到“非ASCII HTML”。如果您正在编写web服务器脚本,并且正在从HTTP请求获取数据,则应检查内容类型头。在理想情况下,它将告诉您客户机对数据使用的编码。请记住,客户可能工作不正常。

希望能有帮助!

相关问题 更多 >