wake-up-neo.net

Python Unicode-Encode-Fehler

Ich lese und parse eine Amazon XML-Datei, und während in der XML-Datei ein 'angezeigt wird, erhalte ich beim Drucken die folgende Fehlermeldung:

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

Was ich bisher online gelesen habe, liegt der Fehler darin, dass sich die XML-Datei in UTF-8 befindet, aber Python möchte es als ASCII -kodiertes Zeichen behandeln. Gibt es eine einfache Möglichkeit, den Fehler zu beheben, und das XML-Programm beim Lesen gedruckt wird?

96
Alex B

Wahrscheinlich besteht Ihr Problem darin, dass Sie es in Ordnung geparst haben, und jetzt versuchen Sie, den Inhalt der XML-Datei zu drucken. Dies ist nicht möglich, da Sie einige fremde Unicode-Zeichen verwenden. Versuchen Sie, Ihre Unicode-Zeichenfolge zuerst als ASCII zu kodieren:

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

der 'Ignorieren'-Teil sagt ihm, diese Zeichen einfach zu überspringen. Aus den Python-Dokumenten:

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

Vielleicht möchten Sie diesen Artikel lesen: http://www.joelonsoftware.com/articles/Unicode.html , was ich als grundlegendes Tutorial für das, was los ist, sehr nützlich fand. Nach dem Lesen hören Sie auf, als würden Sie nur raten, welche Befehle verwendet werden sollen (oder zumindest ist mir das passiert).

178
Scott Stafford

Eine bessere Lösung:

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)

Wenn Sie mehr darüber erfahren möchten, warum:

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

14
Paxwell

Kodieren Sie die Zeichencodierung Ihrer Umgebung nicht in Ihrem Skript. stattdessen Unicode-Text direkt drucken:

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

Wenn Ihre Ausgabe in eine Datei (oder eine Pipe) umgeleitet wird; Sie können PYTHONIOENCODING envvar verwenden, um die Zeichenkodierung anzugeben:

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

Andernfalls sollte python your_script.py so funktionieren, dass die Einstellungen für das Gebietsschema zur Kodierung des Texts verwendet werden (bei POSIX-Prüfung: LC_ALL, LC_CTYPE, LANG envvars - setzen Sie LANG ggf. auf ein utf-8-Gebietsschema).

Informationen zum Drucken von Unicode unter Windows finden Sie in dieser Antwort, die zeigt, wie Unicode an die Windows-Konsole, in eine Datei oder mithilfe von IDLE gedruckt wird.

5
jfs

Ausgezeichnete Post: 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
1
Ranvijay Sachan

Ich schrieb das Folgende, um die lästigen Nicht-Ascii-Anführungszeichen zu korrigieren und die Umwandlung in etwas Nutzbares zu erzwingen.

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

Wenn Sie eine ungefähre Darstellung der Zeichenfolge auf dem Bildschirm ausdrucken möchten, anstatt diese nicht druckbaren Zeichen zu ignorieren, versuchen Sie es mit dem Paket unidecode hier:

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

Die Erklärung finden Sie hier:

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

Dies ist besser als die Verwendung von u.encode('ascii', 'ignore') für eine bestimmte Zeichenfolge u und kann Sie vor unnötigen Kopfschmerzen schützen, wenn die Zeichenpräzision nicht das ist, was Sie suchen, aber dennoch für Menschen lesbar sein soll.

Wirawan

0

Python 3.5, 2018

Wenn Sie nicht wissen, was die Codierung ist, der Unicode-Parser jedoch Probleme hat, können Sie die Datei in Notepad++ öffnen und in der oberen Leiste Encoding->Convert to ANSI auswählen. Dann kannst du deinen Python so schreiben

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

Sie können etwas aus dem Formular verwenden

s.decode('utf-8')

dadurch wird ein UTF-8-codierter Bytestring in einen Python-Unicode-String umgewandelt. Die genaue Vorgehensweise hängt jedoch davon ab, wie genau Sie die XML-Datei laden und analysieren, z. Wenn Sie nie direkt auf den XML-String zugreifen, müssen Sie möglicherweise ein Decoderobjekt aus dem Modul codecs verwenden.

0
David Z