Python Unicode 编码错误

Posted

技术标签:

【中文标题】Python Unicode 编码错误【英文标题】:Python Unicode Encode Error 【发布时间】:2011-03-14 13:09:35 【问题描述】:

我正在读取和解析一个 Amazon XML 文件,当 XML 文件显示一个 ' 时,当我尝试打印它时出现以下错误:

'ascii' codec can't encode character u'\u2019' in position 16: ordinal not in range(128) 

从我目前在网上阅读的内容来看,错误是由于 XML 文件采用 UTF-8 格式,但 Python 希望将其作为 ASCII 编码字符处理。有没有一种简单的方法可以消除错误并让我的程序在读取时打印 XML?

【问题讨论】:

我只是来SO发布这个问题。有没有一种简单的方法来清理unicode() 的字符串? 请查看this 对相关问题的回答:“Python UnicodeDecodeError - 我误解了编码吗?” 【参考方案1】:

很可能,您的问题是您解析它没问题,现在您正尝试打印 XML 的内容,但由于存在一些外来 Unicode 字符而无法打印。尝试先将您的 unicode 字符串编码为 ascii:

unicodeData.encode('ascii', 'ignore')

“忽略”部分会告诉它跳过这些字符。来自 python 文档:

>>> # Python 2: u = unichr(40960) + u'abcd' + unichr(1972)
>>> u = chr(40960) + u'abcd' + chr(1972)
>>> u.encode('utf-8')
'\xea\x80\x80abcd\xde\xb4'
>>> u.encode('ascii')
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
UnicodeEncodeError: 'ascii' codec can't encode character '\ua000' in position 0: ordinal not in range(128)
>>> u.encode('ascii', 'ignore')
'abcd'
>>> u.encode('ascii', 'replace')
'?abcd?'
>>> u.encode('ascii', 'xmlcharrefreplace')
'&#40960;abcd&#1972;'

您可能想阅读这篇文章:http://www.joelonsoftware.com/articles/Unicode.html,我发现它作为关于正在发生的事情的基本教程非常有用。读完之后,您将不再觉得自己只是在猜测要使用什么命令(或者至少在我身上发生过这种情况)。

【讨论】:

我正在尝试使以下字符串安全:' foo “bar bar” df'(请注意大括号),但以上对我来说仍然失败。 @Rosarch:怎么失败了?同样的错误?您使用了哪种错误处理规则? @Rosarch,您的问题可能更早。试试这个代码:# -- coding: latin-1 -- u = u' foo “bar bar” df' print u.encode('ascii', 'ignore') 对你来说,它是考虑到您为引发错误的 python 脚本指定的编码,可能会将您的字符串转换为 unicode。 我继续将我的问题变成了自己的问题:***.com/questions/3224427/… .encode('ascii', 'ignore') 会不必要地丢失数据,即使 OP 的环境可能支持非 ascii 字符(大多数情况下)【参考方案2】:

更好的解决方案:

if type(value) == str:
    # Ignore errors even if the string is not proper UTF-8 or has
    # broken marker bytes.
    # Python built-in function unicode() can do this.
    value = unicode(value, "utf-8", errors="ignore")
else:
    # Assume the value object has proper __unicode__() method
    value = unicode(value)

如果您想了解更多原因:

http://docs.plone.org/manage/troubleshooting/unicode.html#id1

【讨论】:

它对 OP 的问题没有帮助:“无法编码字符 u'\u2019'”u'\u2019 已经是 Unicode。【参考方案3】:

不要在脚本中硬编码环境的字符编码;直接打印 Unicode 文本:

assert isinstance(text, unicode) # or str on Python 3
print(text)

如果您的输出被重定向到文件(或管道);您可以使用PYTHONIOENCODING envvar 来指定字符编码:

$ PYTHONIOENCODING=utf-8 python your_script.py >output.utf8

否则,python your_script.py 应该按原样工作 -- 您的语言环境设置用于对文本进行编码(在 POSIX 检查中:LC_ALLLC_CTYPELANG envvars -- 将 LANG 设置为 utf- 8 语言环境(如有必要)。

To print Unicode on Windows, see this answer that shows how to print Unicode to Windows console, to a file, or using IDLE.

【讨论】:

【参考方案4】:

优秀的帖子:http://www.carlosble.com/2010/12/understanding-python-and-unicode/

# -*- coding: utf-8 -*-

def __if_number_get_string(number):
    converted_str = number
    if isinstance(number, int) or \
            isinstance(number, float):
        converted_str = str(number)
    return converted_str


def get_unicode(strOrUnicode, encoding='utf-8'):
    strOrUnicode = __if_number_get_string(strOrUnicode)
    if isinstance(strOrUnicode, unicode):
        return strOrUnicode
    return unicode(strOrUnicode, encoding, errors='ignore')


def get_string(strOrUnicode, encoding='utf-8'):
    strOrUnicode = __if_number_get_string(strOrUnicode)
    if isinstance(strOrUnicode, unicode):
        return strOrUnicode.encode(encoding)
    return strOrUnicode

【讨论】:

【参考方案5】:

你可以使用某种形式

s.decode('utf-8')

这会将 UTF-8 编码的字节字符串转换为 Python Unicode 字符串。但是要使用的确切过程取决于您加载和解析 XML 文件的方式,例如如果您从不直接访问 XML 字符串,则可能必须使用来自 codecs module 的解码器对象。

【讨论】:

已经用 UTF-8 编码 错误具体是:myStrings = deque([u'Dorf and Svoboda\u2019s text builds on the str... and Computer Engineering\u2019s subdisciplines.'])如您所见,该字符串采用 UTF-8 格式,但它对内部的 '\u2019' 感到很生气 哦,好吧,我以为你遇到了不同的问题。 @Alex B:不,字符串是 Unicode,而不是 Utf-8。要将其编码为 Utf-8,请使用 '...'.encode('utf-8')【参考方案6】:

我写了以下内容来修复令人讨厌的非 ascii 引号并强制转换为可用的东西。

unicodeToAsciiMap = u'\u2019':"'", u'\u2018':"`", 

def unicodeToAscii(inStr):
    try:
        return str(inStr)
    except:
        pass
    outStr = ""
    for i in inStr:
        try:
            outStr = outStr + str(i)
        except:
            if unicodeToAsciiMap.has_key(i):
                outStr = outStr + unicodeToAsciiMap[i]
            else:
                try:
                    print "unicodeToAscii: add to map:", i, repr(i), "(encoded as _)"
                except:
                    print "unicodeToAscii: unknown code (encoded as _)", repr(i)
                outStr = outStr + "_"
    return outStr

【讨论】:

【参考方案7】:

如果您需要将字符串的近似表示打印到屏幕上,而不是忽略那些不可打印的字符,请在此处尝试unidecode 包:

https://pypi.python.org/pypi/Unidecode

解释见这里:

https://www.tablix.org/~avian/blog/archives/2009/01/unicode_transliteration_in_python/

这比对给定字符串 u 使用 u.encode('ascii', 'ignore') 更好,并且如果字符精度不是您所追求的,但仍希望具有人类可读性,则可以避免不必要的麻烦。

维拉万

【讨论】:

【参考方案8】:

尝试在 python 脚本的顶部添加以下行。

# _*_ coding:utf-8 _*_

【讨论】:

【参考方案9】:

Python 3.5,2018 年

如果您不知道编码是什么但 unicode 解析器有问题,您可以在 Notepad++ 中打开文件,然后在顶部栏中选择 Encoding-&gt;Convert to ANSI。然后你可以这样写你的python

with open('filepath', 'r', encoding='ANSI') as file:
    for word in file.read().split():
        print(word)

【讨论】:

以上是关于Python Unicode 编码错误的主要内容,如果未能解决你的问题,请参考以下文章

工作中-错误总结

Python & MySql:Unicode 和编码

Python编码错误:UnicodeEncodeError

Unicode-objects Array Python 3.7

将 pandas df 写入 csv 时出现 Unicode 编码错误

Python3文本编码错误:UnicodeDecodeError: 'gbk' codec can't decode byte