Layer 8Ehrlicher Tech-Support

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. 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. 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. 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. 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. 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.

    open('daten.csv', encoding='utf-8', errors='replace')

Häufige Fragen (FAQ)

?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.

Zuletzt geprüft am . Dokumentation altert – ein Datum daneben ist der einzige ehrliche Umgang damit.

Auch zu finden unter

Verwandte Fehler