Ошибка Кодирования Юникода 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, как он читает?
8 ответов:
вероятно, ваша проблема заключается в том, что вы проанализировали его хорошо, и теперь вы пытаетесь распечатать содержимое XML, и вы не можете, потому что есть некоторые иностранные символы Юникода. Попробуйте сначала закодировать строку unicode как ascii:
unicodeData.encode('ascii', '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, который я нашел очень полезным как основной учебник о том, что происходит. После прочтения вы перестанете чувствовать, что просто угадываете, какие команды использовать (или, по крайней мере, это произошло со мной).
лучшее решение:
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
не жестко кодируйте кодировку символов вашей среды внутри вашего скрипта; вместо этого печатайте текст 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 check:LC_ALL
,LC_CTYPE
,LANG
envvars -- setLANG
к локали utf-8, если необходимый.)
отличный пост : 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
Вы можете использовать что-то вида
s.decode('utf-8')
который преобразует кодировку UTF-8 bytestring в строку Юникода Python. Но точная процедура использования зависит от того, как именно вы загружаете и анализируете XML-файл, например, если вы никогда не обращаетесь к XML-строке напрямую, вам может потребоваться использовать объект декодера из
codecs
модуль.
Я написал следующее, чтобы исправить неприятности без кавычек 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
Если вам нужно напечатать приблизительное представление строки на экране, а не игнорировать эти непечатные символы, попробуйте
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