Python Unicode-Codierungsfehler


104

Ich lese und analysiere eine Amazon XML-Datei und während die XML-Datei ein 'anzeigt, erhalte ich beim Versuch, sie zu drucken, die folgende Fehlermeldung:

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

Nach dem, was ich bisher online gelesen habe, ist der Fehler darauf zurückzuführen, dass sich die XML-Datei in UTF-8 befindet, Python sie jedoch als ASCII-codiertes Zeichen behandeln möchte. Gibt es eine einfache Möglichkeit, den Fehler zu beheben und mein Programm das XML beim Lesen drucken zu lassen?


Ich bin gerade zu SO gekommen, um diese Frage zu stellen. Gibt es eine einfache Möglichkeit, eine Zeichenfolge zu bereinigen unicode()?
Nick Heiner

Bitte überprüfen Sie auch diese Antwort auf eine verwandte Frage: "Python UnicodeDecodeError - Verstehe ich die Codierung falsch?"
Zot

Antworten:


193

Wahrscheinlich besteht Ihr Problem darin, dass Sie es in Ordnung analysiert haben und jetzt versuchen, den Inhalt des XML zu drucken, und Sie können es nicht, weil es einige fremde Unicode-Zeichen gibt. Versuchen Sie zuerst, Ihre Unicode-Zeichenfolge als ASCII zu codieren:

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

Der Teil 'Ignorieren' weist ihn an, 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 , den ich als grundlegendes Tutorial für die Vorgänge sehr nützlich fand. Nach dem Lesen haben Sie nicht mehr das Gefühl, nur zu raten, welche Befehle Sie verwenden sollen (oder zumindest ist mir das passiert).


1
Ich versuche, die folgende Zeichenfolge sicher zu machen: 'foo “bar bar” df' (beachten Sie die geschweiften Anführungszeichen), aber das oben Gesagte schlägt für mich immer noch fehl.
Nick Heiner

@Rosarch: Scheitert wie? gleicher Fehler? Und welche Fehlerbehandlungsregel haben Sie verwendet?
Scott Stafford

@Rosarch, dein Problem ist wahrscheinlich früher. Versuchen Sie diesen Code: # - - Kodierung: latin-1 - - u = u 'foo "Balkenleiste" df' u.encode drucken ('ascii', 'ignorieren') Für Sie war es wahrscheinlich, dass Sie Ihren String in den angegebenen Unicode konvertieren Die Codierung, die Sie für den Python-Scrip angegeben haben, der den Fehler ausgelöst hat.
Scott Stafford

Ich ging voran und machte mein Problem zu einer eigenen Frage: stackoverflow.com/questions/3224427/…
Nick Heiner

1
.encode('ascii', 'ignore')verliert unnötig Daten, selbst wenn die OP-Umgebung (in den meisten Fällen) Nicht-ASCII-Zeichen unterstützt
jfs

16

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/troubleshooting/unicode.html#id1


3
Es hilft nicht bei OPs Problem: "Zeichen u '\ u2019' kann nicht codiert werden" . u'\u2019ist schon Unicode.
JFS

6

Codieren Sie die Zeichenkodierung Ihrer Umgebung in Ihrem Skript nicht fest. Drucken Sie stattdessen direkt Unicode-Text:

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 PYTHONIOENCODINGenvvar verwenden, um die Zeichenkodierung anzugeben:

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

Ansonsten python your_script.pysoll wie arbeiten - Ihre locale - Einstellungen verwendet werden , um den Text zu kodieren (auf POSIX - Check: LC_ALL, LC_CTYPE, LANGenvvars - Satz LANGzu einer utf-8 locale falls erforderlich).

Informationen zum Drucken von Unicode unter Windows finden Sie in dieser Antwort, in der gezeigt wird, wie Unicode auf einer Windows-Konsole, in einer Datei oder mithilfe von IDLE gedruckt wird .


1

Ausgezeichneter Beitrag: 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

0

Sie können etwas von dem Formular verwenden

s.decode('utf-8')

Dadurch wird ein UTF-8-codierter Bytestring in eine Python-Unicode-Zeichenfolge konvertiert. Die genaue Vorgehensweise hängt jedoch davon ab, wie Sie die XML-Datei laden und analysieren. Wenn Sie beispielsweise nie direkt auf die XML-Zeichenfolge zugreifen, müssen Sie möglicherweise ein Decoderobjekt aus dem codecsModul verwenden .


Es ist bereits in UTF-8 codiert. Der Fehler ist speziell: myStrings = deque ([u'Dorf und Svoboda \ u2019s Text baut auf den Unterdisziplinen str ... und Computer Engineering \ u2019s auf. ']) Die Zeichenfolge befindet sich in UTF-8 as Sie können sehen, aber es wird verrückt nach dem internen '\ u2019'
Alex B

Oh, OK, ich dachte du hättest ein anderes Problem.
David Z

7
@Alex B: Nein, die Zeichenfolge ist Unicode, nicht Utf-8. Um es als Utf-8 zu kodieren , benutze'...'.encode('utf-8')
etw

0

Ich habe Folgendes geschrieben, um die lästigen Nicht-ASCII-Anführungszeichen zu korrigieren und die Konvertierung in etwas Verwendbares 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

Wenn Sie eine ungefähre Darstellung der Zeichenfolge auf dem Bildschirm drucken müssen, anstatt diese nicht druckbaren Zeichen zu ignorieren, versuchen Sie bitte das unidecodePaket 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 der u.encode('ascii', 'ignore')Zeichenfolge für eine bestimmte Zeichenfolge uund kann Sie vor unnötigen Kopfschmerzen bewahren, wenn die Zeichengenauigkeit nicht das ist, wonach Sie suchen, aber dennoch eine menschliche Lesbarkeit wünschen.

Wirawan


-1

Fügen Sie die folgende Zeile oben in Ihr Python-Skript ein.

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

-1

Python 3.5, 2018

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

with open('filepath', 'r', encoding='ANSI') as file:
    for word in file.read().split():
        print(word)
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.