UnicodeDecodeError: Der Codec 'utf8' kann das Byte 0xa5 an Position 0 nicht dekodieren: Ungültiges Startbyte


188

Ich verwende Python-2.6 CGISkripte aber diesen Fehler in Server Log gefunden , während tun json.dumps(),

Traceback (most recent call last):
  File "/etc/mongodb/server/cgi-bin/getstats.py", line 135, in <module>
    print json.dumps(​​__getdata())
  File "/usr/lib/python2.7/json/__init__.py", line 231, in dumps
    return _default_encoder.encode(obj)
  File "/usr/lib/python2.7/json/encoder.py", line 201, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/usr/lib/python2.7/json/encoder.py", line 264, in iterencode
    return _iterencode(o, 0)
UnicodeDecodeError: 'utf8' codec can't decode byte 0xa5 in position 0: invalid start byte

Hier,

​__get​data()Funktion kehrt zurück dictionary {}.

Bevor ich diese Frage poste, habe ich diese Frage an SO weitergeleitet.


AKTUALISIERUNG

Die folgende Zeile verletzt den JSON-Encoder.

now = datetime.datetime.now()
now = datetime.datetime.strftime(now, '%Y-%m-%dT%H:%M:%S.%fZ')
print json.dumps({'current_time': now}) // this is the culprit

Ich habe eine vorübergehende Lösung dafür

print json.dumps( {'old_time': now.encode('ISO-8859-1').strip() })

Aber ich bin mir nicht sicher, ob es richtig ist.


1
Es sieht so aus, als hätten Sie einige Zeichenfolgendaten im Wörterbuch, die nicht codiert / decodiert werden können. Was ist in der dict?
mgilson

@mgilson yup master Ich habe das Problem verstanden, aber ich weiß nicht, wie ich damit umgehen soll .. dicthatlist, dict, python timestamp value
Deepak Ingole

1
@Pilot - Nicht wirklich. Das eigentliche Problem ist irgendwo in begraben __getdata. Ich weiß nicht, warum du einen nicht dekodierbaren Charakter bekommst. Sie können versuchen, Patches für das Diktat zu erstellen, damit es funktioniert, aber diese fragen später meist nur nach weiteren Problemen. Ich würde versuchen, das Diktat auszudrucken, um zu sehen, wo sich das Nicht-ASCII-Zeichen befindet. Finden Sie dann heraus, wie dieses Feld berechnet / gesetzt wurde, und arbeiten Sie von dort aus rückwärts.
mgilson


1
Ich hatte den gleichen Fehler beim Versuch, eine CSV-Datei zu lesen, die einige Nicht-ASCII-Zeichen enthielt. Das Entfernen dieser Zeichen (wie unten vorgeschlagen) hat das Problem behoben.
Dmitriy R. Starson

Antworten:


87

Der Fehler liegt darin, dass das Wörterbuch ein Nicht-ASCII-Zeichen enthält und nicht codiert / decodiert werden kann. Eine einfache Möglichkeit, diesen Fehler zu vermeiden, besteht darin, solche Zeichenfolgen mit der folgenden encode()Funktion zu codieren (wenn aes sich um die Zeichenfolge mit Nicht-ASCII-Zeichen handelt):

a.encode('utf-8').strip()

2
Da UTF-8 mit dem 7-Bit-ASCII der alten Schule rückkompatibel ist, sollten Sie einfach alles codieren. Für Zeichen im 7-Bit-ASCII-Bereich ist diese Codierung eine Identitätszuordnung.
Tadeusz A. Kadłubowski

29
Das scheint nicht wirklich klar zu sein. Wie verwenden Sie diesen Code beim Importieren einer CSV-Datei?
Dave

Das gleiche Problem tritt bei der Ausführung einer SQLalchemy-Abfrage auf. Wie würde ich die Abfrage codieren (hat keinen .encode, da es sich nicht um eine Zeichenfolge handelt)?
c8999c 3f964f64

129

Ich habe dies einfach geändert, indem ich im read_csv()Befehl ein anderes Codec-Paket definiert habe :

encoding = 'unicode_escape'

Z.B:

import pandas as pd
data = pd.read_csv(filename, encoding= 'unicode_escape')

1
Nur wenn Sie verwendenpandas
Valeriy

1
Entschuldigung, das hat nicht funktioniert, ich hatte wieder den gleichen Fehler. aber als ich verwendet habe ('filename.csv', engine = 'python'). Das hat funktioniert.
basavaraj_S

117

Versuchen Sie das folgende Code-Snippet:

with open(path, 'rb') as f:
  text = f.read()

7
Ich hatte rstatt rb. danke für die erinnerung zum hinzufügen b!
Paul

1
Standardmäßig hat die openFunktion 'r' als schreibgeschützten Modus. rbsteht für Read Binary Mode.
Shiva

39

In Ihrer Zeichenfolge ist ein Nicht- asciiZeichen codiert.

utf-8Wenn Sie andere Codierungen in Ihrem Code verwenden müssen, kann es vorkommen, dass Sie nicht dekodieren können. Beispielsweise:

>>> 'my weird character \x96'.decode('utf-8')
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 0x96 in position 19: invalid start byte

In diesem Fall müssen windows-1252Sie Folgendes tun:

>>> 'my weird character \x96'.decode('windows-1252')
u'my weird character \u2013'

Jetzt Unicodekönnen Sie sicher codieren utf-8.


1
Ich habe eine einfache Seite erstellt, die dazu beitragen kann, die Codierung einiger unerwarteter "Mystery Bytes" zu ermitteln. Tripleee.github.io/8bit
Tripleee

34

Beim Lesen habe csvich eine Codierungsmethode hinzugefügt:

import pandas as pd
dataset = pd.read_csv('sample_data.csv', header= 0,
                        encoding= 'unicode_escape')

16

Stellen Sie den Standard-Encoder oben in Ihrem Code ein

import sys
reload(sys)
sys.setdefaultencoding("ISO-8859-1")

Ich denke, Python3 hat keine Setdefaulten-Codierung im Sys-Modul!
Anwar Hossain

14

Ab 2018-05 wird dies decodezumindest für Python 3 direkt erledigt .

Ich verwende das folgende Snippet für invalid start byteund invalid continuation bytetippe Fehler ein. Das Hinzufügen hat errors='ignore'es für mich behoben.

with open(out_file, 'rb') as f:
    for line in f:
        print(line.decode(errors='ignore'))

1
Dies verwirft natürlich stillschweigend Informationen. Eine viel bessere Lösung besteht darin, herauszufinden, was dort sein soll, und das ursprüngliche Problem zu beheben.
Tripleee

14

Inspiriert von @aaronpenne und @Soumyaansh

f = open("file.txt", "rb")
text = f.read().decode(errors='replace')

Ich habe "AttributeError: 'str' Objekt hat kein Attribut 'decode'". Nicht sicher, was schief gelaufen ist?
Victor Wong

Haben Sie b in das "rb" aufgenommen? Das b dient zum Öffnen der Datei im Byte-Format. Wenn Sie nur r verwenden, handelt es sich um eine Zeichenfolge, die keine Dekodierung enthält.
Punnerud

14

Diese Lösung hat bei mir funktioniert:

import pandas as pd
data = pd.read_csv("training.csv", encoding = 'unicode_escape')

11

Einfache Lösung:

import pandas as pd
df = pd.read_csv('file_name.csv', engine='python')

3
Danke das hat geholfen!
Ruben

Ich bin froh, @Ruben
Gil Baggio

2
Danke, das hat mir geholfen. Ich habe an Pandas gearbeitet.
Nochmals vielen

Gerne helfen wir @basavaraj_S
Gil Baggio

1
Die einzige Lösung, die für mich von allen hier vorgestellten funktioniert.
Lunesco

7

Die folgende Zeile verletzt den JSON-Encoder.

now = datetime.datetime.now()
now = datetime.datetime.strftime(now, '%Y-%m-%dT%H:%M:%S.%fZ')
print json.dumps({'current_time': now}) // this is the culprit

Ich habe eine vorübergehende Lösung dafür

print json.dumps( {'old_time': now.encode('ISO-8859-1').strip() })

Markieren Sie dies als korrekt als vorübergehende Korrektur (nicht sicher).


5

Wenn die oben genannten Methoden für Sie nicht funktionieren, sollten Sie die Codierung der CSV-Datei selbst ändern.

Verwenden von Excel:

  1. Öffnen Sie die CSV-Datei mit Excel
  2. Navigieren Sie zur Option "Menü Datei" und klicken Sie auf "Speichern unter".
  3. Klicken Sie auf "Durchsuchen", um einen Speicherort für die Datei auszuwählen
  4. Geben Sie den gewünschten Dateinamen ein
  5. Wählen Sie die Option CSV (durch Kommas getrennt) (* .csv)
  6. Klicken Sie auf das Dropdown-Feld "Extras" und dann auf "Weboptionen".
  7. Wählen Sie auf der Registerkarte "Codierung" die Option Unicode (UTF-8) aus der Dropdown-Liste "Dieses Dokument speichern unter" aus
  8. Speicher die Datei

Notepad verwenden:

  1. Öffnen Sie die CSV-Datei mit dem Editor
  2. Navigieren Sie zu "Datei"> "Speichern unter"
  3. Wählen Sie als Nächstes den Speicherort für die Datei aus
  4. Wählen Sie die Option Dateityp als Alle Dateien ( . )
  5. Geben Sie den Dateinamen mit der Erweiterung .csv an
  6. Wählen Sie in der Dropdown-Liste "Codierung" die Option UTF-8 aus.
  7. Klicken Sie auf Speichern, um die Datei zu speichern

Auf diese Weise sollten Sie in der Lage sein, CSV-Dateien zu importieren, ohne auf den UnicodeCodeError zu stoßen.


2

Wenn Sie nach dem Ausprobieren aller oben genannten Problemumgehungen immer noch denselben Fehler auslösen, können Sie versuchen, die Datei als CSV zu exportieren (ein zweites Mal, wenn Sie dies bereits getan haben). Insbesondere wenn Sie scikit learn verwenden, ist es am besten, den Datensatz als CSV-Datei zu importieren.

Ich habe Stunden zusammen verbracht, während die Lösung so einfach war. Exportieren Sie die Datei als CSV in das Verzeichnis, in dem Anaconda oder Ihre Klassifizierertools installiert sind, und versuchen Sie es.


2

Sie können eine beliebige Standardcodierung für Ihre spezifische Verwendung und Eingabe verwenden.

utf-8 ist die Standardeinstellung.

iso8859-1 ist auch in Westeuropa beliebt.

z.B: bytes_obj.decode('iso8859-1')

siehe: docs


1
Das blinde Erraten der Codierung führt wahrscheinlich zu mehr Fehlern. Wenn Sie iso8859-1 oder cp1251 usw. auswählen, ohne tatsächlich zu wissen, welche Codierung die Datei verwendet, wird das Symptom beseitigt, es entsteht jedoch Müll, wenn Sie falsch geraten haben. Wenn es nur ein paar Bytes sind, kann es Jahre dauern, bis Sie den eigentlichen Fehler bemerken und beheben .
Tripleee

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.