UnicodeDecodeError: il codec 'utf8' non può decodificare il byte 0xa5 in posizione 0: byte iniziale non valido


188

Sto usando degli Python-2.6 CGIscript ma ho riscontrato questo errore nel registro del server mentre lo faccio 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

Qui,

​__get​data()la funzione ritorna dictionary {}.

Prima di pubblicare questa domanda ho fatto riferimento a questa domanda SO.


AGGIORNAMENTI

La riga seguente sta danneggiando l'encoder JSON,

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

Ho una soluzione temporanea per questo

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

Ma non sono sicuro sia il modo corretto di farlo.


1
Sembra che nel dizionario siano presenti alcuni dati stringa che non possono essere codificati / decodificati. Cosa c'è nel dict?
mgilson,

@mgilson yup master Ho capito il problema ma donno come affrontarlo .. dicthalist, dict, python timestamp value
Deepak Ingole il

1
@Pilot - Non proprio. Il vero problema è sepolto da qualche parte in __getdata. Non so perché stai ottenendo un personaggio non decodificabile. Puoi provare a trovare delle patch sul dict per farlo funzionare, ma per lo più chiedono più problemi in seguito. Proverei a stampare il dict per vedere dove si trova il personaggio non ascii. Quindi capire come quel campo è stato calcolato / impostato e lavorare all'indietro da lì.
mgilson,


1
Ho avuto lo stesso errore durante il tentativo di leggere un file .csv che conteneva alcuni caratteri non ASCII. La rimozione di quei personaggi (come suggerito di seguito) ha risolto il problema.
Dmitriy R. Starson,

Risposte:


87

L'errore è perché nel dizionario è presente un carattere non ASCII e non può essere codificato / decodificato. Un modo semplice per evitare questo errore è codificare tali stringhe con la encode()funzione come segue (se aè la stringa con carattere non ascii):

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

2
Poiché UTF-8 è retrocompatibile con ASCII a 7 bit oldschool, dovresti semplicemente codificare tutto. Per i caratteri nell'intervallo ASCII a 7 bit questa codifica sarà una mappatura dell'identità.
Tadeusz A. Kadłubowski il

29
Questo non sembra molto chiaro. Quando si importa un file CSV come si utilizza questo codice?
Dave,

Lo stesso problema appare per me quando eseguo una query sqlalchemy, come potrei codificare la query (non ha .encode, poiché non è una stringa)?
c8999c 3f964f64,

132

Ho cambiato questo semplicemente definendo un diverso pacchetto di codec nel read_csv()comando:

encoding = 'unicode_escape'

Per esempio:

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

1
Solo se usipandas
Valeriy il

1
scusa, non ha funzionato, ho avuto di nuovo lo stesso errore. ma quando ho usato ('filename.csv', engine = 'python'). Questo ha funzionato.
basavaraj_S

117

Prova lo snippet di codice seguente:

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

7
Ho avuto rinvece di rb. grazie per il promemoria da aggiungere b!
Paul

1
Per impostazione predefinita, la openfunzione ha 'r' come modalità di sola lettura. rbsta per leggere la modalità binaria.
shiva,

39

La tua stringa ha un non asciicarattere codificato in essa.

Non essere in grado di decodificare utf-8può accadere se è necessario utilizzare altre codifiche nel codice. Per esempio:

>>> '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 questo caso, la codifica è windows-1252quindi devi fare:

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

Ora che hai Unicode, puoi tranquillamente codificarti utf-8.


1
Ho creato una semplice pagina che può aiutare a stabilire la codifica di alcuni "byte misteriosi" imprevisti; tripleee.github.io/8bit
tripleee

34

In lettura csv, ho aggiunto un metodo di codifica:

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

16

Imposta l'encoder predefinito nella parte superiore del codice

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

Penso che python3 non abbia setdefaultencoding nel modulo sys!
Anwar Hossain,

14

A partire dal 2018-05 questo viene gestito direttamente con decode, almeno per Python 3 .

Sto usando il frammento di seguito per invalid start bytee invalid continuation bytedigitare errori. Aggiunta errors='ignore'risolto per me.

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

1
Naturalmente, questo elimina silenziosamente le informazioni. Una soluzione molto migliore è capire cosa dovrebbe esserci e risolvere il problema originale.
tripla il

14

Ispirato da @aaronpenne e @Soumyaansh

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

Ho ottenuto "AttributeError: l'oggetto 'str' non ha attributi 'decodifica'". Non sei sicuro di cosa sia andato storto?
Victor Wong,

Hai incluso b nella "rb"? La b serve per aprire il file come formato byte. Se usi solo r, è stringa e non includere la decodifica.
Punnerud,

14

Questa soluzione ha funzionato per me:

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

11

Soluzione semplice:

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

3
Grazie che mi ha aiutato!
Ruben,

Sono contento di aiutare @Ruben
Gil Baggio il

2
Grazie questo mi ha aiutato. Stavo lavorando sui panda. Grazie ancora
basavaraj_S il

Felice di aiutare @basavaraj_S
Gil Baggio il

1
L'unica soluzione che funziona per me di tutti quelli presentati qui.
lunesco,

7

La riga seguente sta danneggiando l'encoder JSON,

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

Ho una soluzione temporanea per questo

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

Contrassegnando questo come corretto come una correzione temporanea (non sono sicuro).


5

Se i metodi sopra indicati non funzionano per te, potresti voler esaminare la modifica della codifica del file CSV stesso.

Utilizzando Excel:

  1. Apri il file CSV utilizzando Excel
  2. Passare all'opzione "Menu file" e fare clic su "Salva con nome"
  3. Fai clic su "Sfoglia" per selezionare un percorso in cui salvare il file
  4. Inserisci il nome file desiderato
  5. Seleziona l'opzione CSV (delimitato da virgole) (* .csv)
  6. Fai clic sulla casella a discesa "Strumenti" e fai clic su "Opzioni Web"
  7. Nella scheda "Codifica", seleziona l'opzione Unicode (UTF-8) dall'elenco a discesa "Salva questo documento come"
  8. Salva il file

Utilizzando il Blocco note:

  1. Apri il file CSV usando il blocco note
  2. Passare all'opzione "File"> "Salva con nome"
  3. Quindi, selezionare la posizione del file
  4. Seleziona l'opzione Salva come tipo come Tutti i file ( . )
  5. Specificare il nome del file con estensione .csv
  6. Dall'elenco a discesa "Codifica", selezionare l'opzione UTF-8.
  7. Fai clic su Salva per salvare il file

In questo modo, dovresti essere in grado di importare file CSV senza incontrare UnicodeCodeError.


2

Dopo aver provato tutte le soluzioni alternative di cui sopra, se genera ancora lo stesso errore, puoi provare a esportare il file come CSV (una seconda volta se lo hai già fatto). Soprattutto se usi scikit learn, è meglio importare il set di dati come file CSV.

Ho trascorso ore insieme, mentre la soluzione era così semplice. Esporta il file come CSV nella directory in cui sono installati Anaconda o gli strumenti di classificazione e prova.


2

È possibile utilizzare qualsiasi codifica standard per l'utilizzo e l'input specifici.

utf-8 è l'impostazione predefinita.

iso8859-1 è anche popolare per l'Europa occidentale.

per esempio: bytes_obj.decode('iso8859-1')

vedi: docs


1
Indovinare ciecamente la codifica probabilmente produrrà più errori. Selezionando iso8859-1 o cp1251 ecc. Senza effettivamente sapere quale codifica il file utilizza rimuoverà il sintomo, ma produrresti spazzatura se hai indovinato. Se sono solo pochi byte, potrebbero volerci anni prima di notare e correggere il vero errore.
tripla il

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.