2010-08-13 24 views
10

Sto leggendo in un file con il modulo csv di Python e ho ancora un'altra domanda di codifica (scusa, ce ne sono così tante qui).Python csv: UnicodeDecodeError

Nel file CSV, ci sono segni £. Dopo aver letto la riga e averla stampata, sono diventate \ xa3.

Cercando di codificarli come Unicode produce una UnicodeDecodeError:

row = [unicode(x.strip()) for x in row] 
UnicodeDecodeError: 'ascii' codec can't decode byte 0xa3 in position 0: ordinal not in range(128) 

Ho letto il csv documentation e le numerose altre domande su questo su StackOverflow. I penso a che £ diventando \ xa3 in ASCII significa che il file CSV originale è in UTF-8.

(Per inciso, c'è un modo rapido per verificare la codifica di un file CSV?)

Se è in UTF-8, quindi il modulo csv non dovrebbe essere in grado di farvi fronte? Sembra che stia trasformando tutti i simboli in ASCII, anche se la documentazione afferma che accetta UTF-8.

Ho provato ad aggiungere una funzione unicode_csv_reader come descritto nello csv examples, ma non aiuta.

---- EDIT -----

vorrei chiarire una cosa. Ho visto this question, che sembra molto simile. Ma aggiungendo la funzione unicode_csv_reader definita non produce un errore diverso, invece:

yield [unicode(cell, 'utf-8') for cell in row] 
UnicodeDecodeError: 'utf8' codec can't decode byte 0xa3 in position 8: unexpected code byte 

Quindi forse il mio file non è UTF8, dopo tutto? Come posso dire?

risposta

7

Provare a utilizzare "ISO-8859-1" per la codifica. Sembra che tu abbia a che fare con ASCII esteso, non con Unicode.

Edit:

Ecco qualche semplice codice che si occupa di ASCII estesi:

>>> s = "La Pe\xf1a" 
>>> print s 
La Pe±a 
>>> print s.decode("latin-1") 
La Peña 
>>> 

Ancora meglio, che fare con il carattere esatto che si sta dando problemi:

>>> s = "12\xa3" 
>>> print s.decode("latin-1") 
12£ 
>>> 
+0

cosa si intende utilizzare: la resa [unicode (cella, 'ISO-8859-1') per la cellula in riga], invece, nella funzione unicode_csv_reader? Sfortunatamente questo non aiuta - ritorna di nuovo all'errore ordinale non nel range (128). – AP257

+0

Non avrebbe molto senso usare una funzione chiamata unicode() quando si ha a che fare con ASCII. Quello che sto dicendo è che hai a che fare con un file codificato usando una codifica "ISO-8859-1".Non ho inserito alcun codice, perché non so come farlo fuori di testa, ma il tuo problema è che devi decodificarlo come ISO-8859-1, non come Unicode. – riwalk

+0

OK, grazie. Indagherò Come sapevi che era ISO-8859-1? In altre parole, c'è un modo per me di controllare me stesso le codifiche, piuttosto che semplicemente porre domande stupide su StackOverflow :) – AP257

0

Se sono su Windows, è molto probabile che la codifica che dovresti usare sia una della famiglia cp125X ... es se sei in Europa occidentale o nelle Americhe, sarà cp1252. Il software Windows utilizza spesso i byte nell'intervallo da \x80 a \x9F incluso per codificare i caratteri di punteggiatura di fantasia mentre tale intervallo è riservato in ISO-8859-X per i "caratteri di controllo C1" usati raramente.

Si può scoprire la solita codifica nel vostro locale eseguendo questo nella riga di comando:

python -c "import locale; print locale.getpreferredencoding()" 
+0

Ha difficoltà a leggere i segni £, e tu stai dando per scontato che il file sia stato opportunamente salvato su qualunque impostazione * preferisca il suo * computer? Farei attenzione nell'assumere che il file sia qualcosa che è stato salvato usando la sua macchina. – riwalk

+0

@ Stargazer712: No, non sto assumendo nulla. Sto suggerendo che è altamente probabile che il file sia stato creato su una macchina nello stesso locale e che utilizzi lo stesso sistema operativo della macchina che l'OP sta usando. –

+0

La mia esperienza con le codifiche (come ho detto prima) proviene dal scraping del web. Ti assicuro che non è un presupposto sicuro. – riwalk