UnicodeDecodeError, ungültiges Fortsetzungsbyte

257

Warum schlägt der folgende Punkt fehl? und warum gelingt es mit "latin-1" codec?

o = "a test of \xe9 char" #I want this to remain a string as this is what I am receiving
v = o.decode("utf-8")

Ergebnisse in:

 Traceback (most recent call last):  
 File "<stdin>", line 1, in <module>  
 File "C:\Python27\lib\encodings\utf_8.py",
 line 16, in decode
     return codecs.utf_8_decode(input, errors, True) UnicodeDecodeError:
 'utf8' codec can't decode byte 0xe9 in position 10: invalid continuation byte
RuiDC
quelle

Antworten:

247

In Binärform sieht 0xE9 so aus 1110 1001. Wenn Sie in Wikipedia über UTF-8 lesen , werden Sie feststellen, dass auf ein solches Byte zwei der Formulare folgen müssen 10xx xxxx. Also zum Beispiel:

>>> b'\xe9\x80\x80'.decode('utf-8')
u'\u9000'

Aber das ist nur die mechanische Ursache der Ausnahme. In diesem Fall haben Sie eine Zeichenfolge, die mit ziemlicher Sicherheit in Latein 1 codiert ist. Sie können sehen, wie UTF-8 und Latein 1 unterschiedlich aussehen:

>>> u'\xe9'.encode('utf-8')
b'\xc3\xa9'
>>> u'\xe9'.encode('latin-1')
b'\xe9'

(Beachten Sie, dass ich hier eine Mischung aus Python 2- und 3-Darstellung verwende. Die Eingabe ist in jeder Version von Python gültig, aber es ist unwahrscheinlich, dass Ihr Python-Interpreter auf diese Weise tatsächlich sowohl Unicode- als auch Byte-Zeichenfolgen anzeigt.)

Josh Lee
quelle
2
Dank (und dem anderen, der geantwortet hat) war ich der falschen Überzeugung, dass Zeichen bis 255 direkt konvertieren würden.
RuiDC
Ich bekomme UnicodeEncodeError: 'ascii' codec can't encode characters in position 2-3: ordinal not in range(128)Fehler bei der Verwendung.encode(latin-1)
Shiva
234

Ich hatte den gleichen Fehler, als ich versuchte, eine CSV-Datei mit der Methode pandas read_csv zu öffnen.

Die Lösung bestand darin, die Codierung in "Latin-1" zu ändern:

pd.read_csv('ml-100k/u.item', sep='|', names=m_cols , encoding='latin-1')
Mazen Aly
quelle
1
Löst dies das Problem tatsächlich? Weist es Pandas nicht einfach an, das Byte durch Herabstufen auf einen weniger komplexen Codierungsstil zu ignorieren?
Yu Chen
61

Es ist ungültig UTF-8. Dieses Zeichen ist das e-akute Zeichen in ISO-Latin1, weshalb es mit diesem Codesatz erfolgreich ist.

Wenn Sie den Codesatz, in dem Sie Zeichenfolgen erhalten, nicht kennen, haben Sie Probleme. Es ist am besten, wenn ein einzelner Codesatz (hoffentlich UTF-8) für Ihr Protokoll / Ihre Anwendung ausgewählt wird und Sie dann nur diejenigen ablehnen, die nicht dekodiert wurden.

Wenn Sie das nicht können, benötigen Sie Heuristiken.

Sami J. Lehtinen
quelle
2
Heuristiken finden Sie in der Chardet-Bibliothek.
mlissner
44

Weil UTF-8 ein Multibyte ist und es kein Zeichen gibt, das Ihrer Kombination von entspricht \xe9 Plus-Leerzeichen entspricht.

Warum sollte es sowohl in utf-8 als auch in latein-1 gelingen ?

Hier, wie der gleiche Satz in utf-8 sein sollte:

>>> o.decode('latin-1').encode("utf-8")
'a test of \xc3\xa9 char'
Neurino
quelle
Latin-1 ist eine Einzelbyte-Codierungsfamilie, daher sollte alles darin in UTF-8 definiert werden. Aber warum gewinnt Latin-1 irgendwann?
Reihan_amn
11

Wenn dieser Fehler beim Bearbeiten einer gerade geöffneten Datei auftritt, überprüfen Sie, ob Sie sie im 'rb'Modus geöffnet haben

Patrick Mutuku
quelle
2
Dank dieser Antwort konnte der Fehler von UnicodeDecodeError vermieden werden: Der Codec 'utf-8' kann das Byte 0xd7 in Position 2024079 nicht dekodieren: Ungültiges Fortsetzungsbyte von soup = BeautifulSoup(open('webpage.html', 'rb'), 'html.parser')
Isaac Philip
6

Dies passierte mir auch, als ich Text mit Hebräisch aus einer .txtDatei las .

Ich habe geklickt: file -> save asund diese Datei als UTF-8Codierung gespeichert

Alon Gouldman
quelle
5

Der utf-8-Codefehler tritt normalerweise auf, wenn der Bereich der numerischen Werte 0 bis 127 überschreitet.

Der Grund für diese Ausnahme ist:

1) Wenn der Codepunkt <128 ist, entspricht jedes Byte dem Wert des Codepunkts. 2) Wenn der Codepunkt 128 oder höher ist, kann die Unicode-Zeichenfolge in dieser Codierung nicht dargestellt werden. (Python löst in diesem Fall eine UnicodeEncodeError-Ausnahme aus.)

Um dies zu überwinden, haben wir eine Reihe von Codierungen. Die am häufigsten verwendete ist "Latin-1, auch bekannt als ISO-8859-1".

ISO-8859-1-Unicode-Punkte 0–255 sind also mit den Latin-1-Werten identisch. Für die Konvertierung in diese Codierung müssen lediglich Codepunkte in Bytewerte konvertiert werden. Wenn ein Codepunkt größer als 255 gefunden wird, kann die Zeichenfolge nicht in Latin-1 codiert werden

Wenn diese Ausnahme auftritt, wenn Sie versuchen, einen Datensatz zu laden, versuchen Sie, dieses Format zu verwenden

df=pd.read_csv("top50.csv",encoding='ISO-8859-1')

Fügen Sie am Ende der Syntax eine Codierungstechnik hinzu, die dann das Laden des Datensatzes akzeptiert.

Surya
quelle
Hallo und willkommen bei SO! Bitte bearbeiten Sie Ihre Antwort, um sicherzustellen, dass sie andere Antworten verbessert, die bereits in dieser Frage enthalten sind.
Hongsy
4

Verwenden Sie diese Option, wenn der Fehler von UTF-8 angezeigt wird

pd.read_csv('File_name.csv',encoding='latin-1')
Anshul Singh Suryan
quelle
-1

In diesem Fall habe ich versucht, eine .py-Datei auszuführen, die einen Pfad / eine Datei.sql aktiviert.

Meine Lösung bestand darin, die Codierung der Datei file.sql in "UTF-8 ohne Stückliste" zu ändern, und es funktioniert!

Sie können dies mit Notepad ++ tun.

Ich werde einen Teil meines Codes hinterlassen.

/ Code /

con = psycopg2.connect (host = sys.argv [1], port = sys.argv [2], dbname = sys.argv [3], user = sys.argv [4], password = sys.argv [5] )

cursor = con.cursor () sqlfile = open (Pfad, 'r')

Martin Taco
quelle