Python: UnicodeDecodeError beim Einlesen einer Datei
Python bricht beim Öffnen einer Datei mit UnicodeDecodeError ab. Die Datei ist meist heil – es passt nur die angenommene Zeichenkodierung nicht.
Aufwand:
ca. 15 Min.
Gilt für:
Python 3 (alle aktuellen Versionen)
Das Symptom
Ein Skript, das eine Text- oder CSV-Datei einliest, bricht mit einer Zeile wie dieser ab:
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xdf in position 12: invalid continuation byte
Oft passiert das ausgerechnet bei einer Datei, die im Editor völlig normal aussieht –
und manchmal nur auf einem der beteiligten Rechner.
Die „Layer 8“-Wahrheit
Der Fehler klingt nach Datenverlust und ist keiner. Eine Datei speichert nur Bytes; welche
Buchstaben daraus werden, entscheidet die Kodierung, mit der man sie liest. Ein Umlaut
sieht als UTF-8 anders aus als in Windows-1252, und wer die Bytes des einen mit den Regeln
des anderen deutet, stößt irgendwann auf eine Bytefolge, die keinen Sinn ergibt. Genau da
bricht Python ab. Die Datei ist heil – die Annahme über sie war falsch.
Der tückische Teil steckt in dem Satz „bei mir läuft es doch“. Ruft man open(datei) ohne
weitere Angabe auf, nimmt Python die Kodierung des Betriebssystems, und die ist nicht
überall gleich. Auf dem Linux-Server ist es meist UTF-8, auf dem Windows-Laptop
traditionell etwas anderes. Dasselbe Skript liest dieselbe Datei dann unterschiedlich, und
der Fehler wandert von Rechner zu Rechner wie ein Gespenst. Die Lösung ist unspektakulär:
die Kodierung nicht dem Zufall des Systems überlassen, sondern hinschreiben. UTF-8 für
alles aus dem Netz, Windows-1252 für alte Excel-Exporte, und wenn man es partout nicht
weiß, lässt man es schätzen. Nur errors='replace' ist kein Öffnen, sondern ein
Wegschauen: Es macht das Programm ruhig, indem es die strittigen Zeichen still verfälscht.
Das darf man tun – aber man muss wissen, dass man es tut.
Die echte, verifizierte Lösung
1000 % faktenbasiert. Jeder Befehl ist real, jeder Pfad existiert. Schritt für Schritt:
1.
Die Panik über Bord werfen: Die Datei ist wahrscheinlich heil
UnicodeDecodeError heißt nicht, dass die Datei beschädigt ist. Er heißt, dass Python die Bytes mit einer Kodierung zu lesen versucht, zu der sie nicht passen. Ein einzelnes Byte, das in UTF-8 keinen gültigen Anfang hat, reicht für den Abbruch – der Rest der Datei kann völlig in Ordnung sein.
2.
Die Kodierung beim Öffnen ausdrücklich nennen
Statt sich auf die Voreinstellung zu verlassen, gibt man die Kodierung an. Kommt die Datei aus dem Web oder von einem Linux-System, ist UTF-8 die richtige erste Vermutung. Die ausdrückliche Angabe macht das Programm außerdem unabhängig davon, auf welchem Rechner es läuft.
open('daten.csv', encoding='utf-8')
3.
Bei Windows-Exporten die passende Kodierung wählen
Stammt die Datei aus Excel oder einem älteren Windows-Programm, ist sie oft nicht UTF-8, sondern Windows-1252 (auch cp1252 genannt). Dann ist nicht UTF-8 falsch, sondern die Datei einfach anders kodiert – und mit der richtigen Angabe liest sie sich fehlerfrei.
open('daten.csv', encoding='cp1252')
4.
Wenn die Kodierung unbekannt ist, sie messen statt raten
Weiß man es nicht, hilft ein Erkennungswerkzeug, das die wahrscheinliche Kodierung aus den Bytes schätzt. Das ist eine Schätzung, kein Beweis – aber ein guter Startpunkt, um die richtige Angabe zu finden, statt sie durchzuprobieren.
python -m pip install charset-normalizer
5.
errors='replace' nur als letzte, ehrliche Notlösung
Man kann Python anweisen, unlesbare Bytes durch ein Ersatzzeichen zu ersetzen, statt abzubrechen. Das Programm läuft dann durch – aber die betroffenen Zeichen sind unwiederbringlich verfälscht. Das ist vertretbar, wenn es nur ums grobe Überfliegen geht, und ein Fehler, wenn die Daten stimmen müssen.
?Warum läuft es auf einem Rechner und auf dem anderen nicht?
Weil Python ohne ausdrückliche Angabe die Kodierung des Systems benutzt, und die ist plattformabhängig. Auf vielen Linux-Systemen ist das UTF-8, auf Windows traditionell eine andere. Dieselbe Zeile open(datei) liest die Datei also je nach Rechner unterschiedlich – der Klassiker hinter „läuft bei mir“. Wer die Kodierung im Code nennt, macht das Programm überall gleich.
?Ist meine Datei jetzt kaputt?
Fast nie. Der Fehler entsteht beim Lesen, nicht beim Speichern – die Bytes auf der Platte sind unverändert. Sobald man mit der richtigen Kodierung öffnet, ist alles da. Erst wenn man mit errors='replace' liest und das Ergebnis wieder speichert, geht tatsächlich Information verloren. Solange man nur liest, kann man beliebig oft die passende Kodierung suchen.
Belege
Diese Seite ist gegen die folgenden Primärquellen geprüft – Hersteller, Standard oder Gesetzestext. Wer es nicht glaubt, muss es nicht: Da steht, wo es nachzulesen ist.