Ошибка Кодирования Юникода 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 93

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')
'&#40960;abcd&#1972;'

вы можете прочитать эту статью: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 -- set LANG к локали utf-8, если необходимый.)

чтобы напечатать Unicode в Windows, см. Этот ответ, в котором показано, как печатать Unicode в консоль Windows, в файл или с помощью IDLE.

отличный пост : 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

попробуйте добавить следующую строку в верхней части вашего скрипта Python.

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