Ошибка кодирования Unicode Python
Я читаю и разбираю XML файл Amazon, а в то время как файл XML показывает ", когда я пытаюсь его распечатать, я получаю следующую ошибку:
'ascii' codec can't encode character u'\u2019' in position 16: ordinal not in range(128)
Из того, что я читал в Интернете до сих пор, ошибка исходит из того факта, что XML файл находится в UTF-8, но Python хочет обрабатывать его как ASCII-кодированный символ. Есть ли простой способ, чтобы ошибка исчезла, и моя программа печатает XML по мере его чтения?
Ответы
Ответ 1
Вероятно, ваша проблема в том, что вы разобрали его в порядке, и теперь вы пытаетесь распечатать содержимое XML, и вы не можете, потому что есть некоторые иностранные символы Unicode. Попробуйте сначала кодировать строку юникода как ascii:
unicodeData.encode('ascii', 'ignore')
часть "ignore" сообщит ему просто пропустить эти символы. Из документов python:
>>> u = unichr(40960) + u'abcd' + unichr(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')
'ꀀabcd޴'
Возможно, вы захотите прочитать эту статью: http://www.joelonsoftware.com/articles/Unicode.html, который я нашел очень полезным в качестве основного учебника о том, что происходит. После чтения вы перестанете чувствовать, что вы просто угадываете, какие команды использовать (или, по крайней мере, это случилось со мной).
Ответ 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
Ответ 3
Не скопируйте кодировку символов вашей среды внутри script; напечатайте текст 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_ALL
, LC_CTYPE
, LANG
envvars - установите LANG
в utf- 8, если необходимо).
Чтобы напечатать Unicode в Windows, см. этот ответ, который показывает, как печатать Unicode в консоли Windows, в файл или с помощью 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 байтовую строку в строку Unicode Python. Но точная процедура использования зависит от того, как вы загружаете и разбираете XML файл, например. если вы никогда не обращаетесь непосредственно к строке XML, вам может потребоваться использовать объект декодера из codecs
module.
Ответ 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
Попробуйте добавить следующую строку вверху вашего python script.
# _*_ coding:utf-8 _*_
Ответ 8
Если вам нужно напечатать приблизительное представление строки на экране, а не игнорировать эти непечатаемые символы, попробуйте unidecode
здесь:
https://pypi.python.org/pypi/Unidecode
Объяснение можно найти здесь:
https://www.tablix.org/~avian/blog/archives/2009/01/unicode_transliteration_in_python/
Это лучше, чем использование u.encode('ascii', 'ignore')
для данной строки u
и может избавить вас от ненужной головной боли, если точность символов не то, что вы после, но все же хотите иметь человеческую читаемость.
Wirawan