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.

Deepak Ingole
quelle
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()
Santosh Ghimire
quelle
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')
MSalty
quelle
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()
Koralle
quelle
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.

JCF
quelle
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')
Krishna prasad.m
quelle
16

Stellen Sie den Standard-Encoder oben in Ihrem Code ein

import sys
reload(sys)
sys.setdefaultencoding("ISO-8859-1")
HimalayanCoder
quelle
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'))
Aaronpenne
quelle
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')
Punnerud
quelle
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')
Shiva
quelle
11

Einfache Lösung:

import pandas as pd
df = pd.read_csv('file_name.csv', engine='python')
Gil Baggio
quelle
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).

Deepak Ingole
quelle
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.

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

Sushmita
quelle
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

NoamG
quelle
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