"For line in ..." führt zu UnicodeDecodeError: Der Codec 'utf-8' kann kein Byte dekodieren

214

Hier ist mein Code,

for line in open('u.item'):
#read each line

Wenn ich diesen Code ausführe, wird der folgende Fehler ausgegeben:

UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe9 in position 2892: invalid continuation byte

Ich habe versucht, dies zu lösen und einen zusätzlichen Parameter in open () hinzuzufügen. Der Code sieht so aus.

for line in open('u.item', encoding='utf-8'):
#read each line

Aber es gibt wieder den gleichen Fehler. was sollte ich dann tun! Bitte helfen Sie.

Sujits
quelle
3
Schlecht codierte Daten würde ich annehmen.
Andreas Jung
9
Oder einfach keine UTF-8-Daten.
Mark Tolonen
Wir hatten diesen Fehler mit msgpack, wenn wir Python 3 anstelle von Python 2.7 verwendeten. Für uns bestand die Vorgehensweise darin, mit Python 2.7 zu arbeiten.
Jesse W. Collins

Antworten:

402

Wie von Mark Ransom vorgeschlagen, habe ich die richtige Codierung für dieses Problem gefunden. Die Codierung war "ISO-8859-1", daher wird das Problem durch Ersetzen open("u.item", encoding="utf-8")durch ersetzt open('u.item', encoding = "ISO-8859-1").

Sujits
quelle
8
Explizit ist besser als implizit (PEP 20).
Ioannis Filippidis
6
Der Trick besteht darin, dass ISO-8859-1 oder Latin_1 8-Bit-Zeichensätze sind, sodass jeder Müll einen gültigen Wert hat. Vielleicht nicht verwendbar, aber wenn Sie ignorieren wollen!
Kjeld Flarup
1
Ich hatte das gleiche Problem UnicodeDecodeError: Der Codec 'utf-8' kann das Byte 0xd0 an Position 32 nicht dekodieren: Ungültiges Fortsetzungsbyte. Ich habe Python 3.6.5 verwendet, um aws cli zu installieren. Und als ich aws --version versuchte, schlug es mit diesem Fehler fehl. Also musste ich /Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/configparser.py bearbeiten und den Code in den folgenden def read
27вгений Коптюбенко
3
Gibt es eine automatische Methode zum Erkennen der Codierung?
OrangeSherbet
5
@OrangeSherbet Ich habe die Erkennung mit implementiert chardet. Hier ist der Einzeiler (nach import chardet) : chardet.detect(open(in_file, 'rb').read())['encoding']. Überprüfen Sie heraus diese Antwort für Details: stackoverflow.com/a/3323810/615422
VertigoRay
51

Auch für mich hat ISO 8859-1 viel gespart, hahaha, hauptsächlich wenn Spracherkennungs-APIs verwendet werden

Beispiel:

file = open('../Resources/' + filename, 'r', encoding="ISO-8859-1");
Ryoji Kuwae Neto
quelle
4
Sie können richtig sein, dass das OP ISO 8859-1 liest, wie aus dem 0xe9 (é) in der Fehlermeldung abgeleitet werden kann, aber Sie sollten erklären, warum Ihre Lösung funktioniert. Der Verweis auf Spracherkennungs-APIs hilft nicht.
RolfBly
5
Was ist mit dem Semikolon?
Rechtes Bein
29

Ihre Datei enthält keine utf-8-codierten Daten, sondern eine andere Codierung. Finden Sie heraus, was diese Codierung ist, und verwenden Sie sie im openAufruf.

Bei der Windows-1252-Codierung 0xe9wäre dies beispielsweise das Zeichen é.

Mark Ransom
quelle
4
Wie kann ich herausfinden, um welche Codierung es sich handelt? Ich benutze Linux
SujitS
3
Es gibt keine Möglichkeit, dies zu tun, die immer funktioniert, aber siehe die Antwort auf diese Frage: stackoverflow.com/questions/436220/…
RemcoGerlich
20

Versuchen Sie dies, um mit Pandas zu lesen

pd.read_csv('u.item', sep='|', names=m_cols , encoding='latin-1')
Shashank
quelle
Ich bin mir nicht sicher, warum du Pandas vorschlägst. Die Lösung besteht darin, die richtige Codierung festzulegen, auf die Sie hier zufällig gestoßen sind.
Alastair McCormack
12

Wenn Sie Python 2Folgendes verwenden, wird die Lösung:

import io
for line in io.open("u.item", encoding="ISO-8859-1"):
    # do something

Da der encodingParameter nicht funktioniert open(), wird der folgende Fehler angezeigt:

TypeError: 'encoding' ist ein ungültiges Schlüsselwortargument für diese Funktion
Jeril
quelle
1
Aber das ist Version 3
SujitS
1
Ja ich weiß. Ich dachte, es könnte für die Leute hilfreich sein, diePython 2
Jeril
Arbeitete auch für mich in Python3
Fenkerbb
2
Wenn Sie sich etwas leichter merken möchten, 'ISO-8859-1'wird dies auch als 'latin-1'oder bezeichnet 'latin1'.
Max Candocia
9

Sie können das Problem beheben mit:

for line in open(your_file_path, 'rb'):

'rb' liest eine Datei im Binärmodus. Lesen Sie hier mehr . Hoffe das wird helfen!

Ozcar Nguyen
quelle
5

Das funktioniert:

open('filename', encoding='latin-1')

oder:

open('filename',encoding="IS0-8859-1")
Ayesha Siddiqa
quelle
2

Wenn jemand nach diesen sucht, ist dies ein Beispiel für die Konvertierung einer CSV-Datei in Python 3:

try:
    inputReader = csv.reader(open(argv[1], encoding='ISO-8859-1'), delimiter=',',quotechar='"')
except IOError:
    pass
user6832484
quelle
2

Manchmal , wenn open(filepath)in dem filepathMoment nicht eine Datei würde den gleichen Fehler, so zunächst sicherstellen , dass die Datei , die Sie versuchen , sind offen vorhanden ist :

import os
assert os.path.isfile(filepath)

hoffe das wird helfen.

xtluo
quelle
1

Sie können dies folgendermaßen versuchen:

open('u.item', encoding='utf8', errors='ignore')
FaridLU
quelle
Dies gibt keine Antwort auf die Frage. Um einen Autor zu kritisieren oder um Klarstellung zu bitten, hinterlassen Sie einen Kommentar unter seinem Beitrag. - Aus dem Review
MartenCatcher