2013-08-27 19 views
9

Come progetto per aiutarmi ad imparare Python, sto creando un visualizzatore CMD di Reddit utilizzando i dati di JSON (ad esempio www.reddit.com/all/ .json). Quando alcuni messaggi vengono visualizzati e provo a stamparli (questo è quello che presumo sta causando l'errore), ottengo questo errore:Impossibile stampare il carattere ' u2019' in Python dall'oggetto JSON

Traceback (ultima chiamata ultima): File "C: \ Users \ nsaba \ Desktop \ reddit_viewer.py ", riga 33, nella stampa ("% d. (% d)% s \ n "% (i + 1, obj [" dati "] [" punteggio "], obj [" dati "] [ 'title']))

file "C: \ Python33 \ lib \ codifiche \ cp437.py", linea 19, nel codificare codecs.charmap_encode ritorno (ingresso, self.errors, encoding_map) [0] UnicodeEncodeError: codec 'charmap' non può codificare il carattere '\ u2019' nella posizione 32: mappe di caratteri su

Qui è dove mi occupo dei dati:

request = urllib.request.urlopen(url) 
content = request.read().decode('utf-8') 
jstuff = json.loads(content) 

La linea che uso per stampare i dati elencati l'errore precedente:

print ("%d. (%d) %s\n" % (i+1, obj['data']['score'], obj['data']['title'])) 

Qualcuno può suggerire dove potrebbe andare storto?

+0

Il problema quasi certamente non ha nulla a che fare con JSON, o con qualsiasi altra cosa nel codice. Prova semplicemente a 'print ('\ u2019')' e vedi se ottieni lo stesso errore. Se è così, il problema è che il tuo terminale ("scatola DOS") non è impostato per fare in modo che l'uscita Unicode funzioni correttamente, ed è quello che devi correggere. – abarnert

+0

Sì hai ragione. La ragione per i dati extra è perché ho imparato a porre domande date le informazioni che ho, e non su ciò che penso possa essere. –

+1

Ma dovresti pubblicare l'esempio completo minimo che mostri il tuo problema. Ecco cos'è un [SSCCE] (http://sscce.org). Se 'print ('\ u2019')' è sufficiente per dimostrarlo, un esempio più complicato è solo quello di guidare le persone su inseguimenti di oche selvagge. Se sei preoccupato, le persone potrebbero chiedere "Perché vuoi stampare quel personaggio?", Quindi puoi aggiungere il contesto che lo spiega ... ma ancora, portare il problema reale. – abarnert

risposta

18

E 'quasi certo che si problema non ha nulla a che fare con il codice che hai mostrato, e può essere riprodotto in una sola riga:

print(u'\2019') 

Se il set di caratteri del terminale non è in grado di gestire U + 2019 (o se Python è confuso su quale set di caratteri usi il terminale), non c'è modo di stamparlo. Non importa se proviene da JSON o da qualsiasi altra parte.

Il terminale di Windows (noto anche come "prompt DOS" o "finestra cmd") viene solitamente configurato per un set di caratteri come cp1252 che conosce solo 256 dei 110000 caratteri, e non c'è nulla che Python possa fare al riguardo senza un grosso cambiamento all'implementazione del linguaggio. *

Vedere PrintFails sul Wiki Python per dettagli, soluzioni alternative e collegamenti a ulteriori informazioni. Ci sono anche alcune centinaia di duplicati di questo problema su SO (anche se molti di essi saranno specifici per Python 2.x, senza menzionarlo).


* Windows ha un insieme separato di API per la stampa UTF-16 al terminale, in modo Python potrebbe rilevare che stdout è un terminale di Windows, e se così codificare UTF-16 e utilizzare le API speciali invece di codifica per il set di caratteri del terminale e utilizzando quelli standard. Ma ciò solleva una serie di problemi diversi (ad es., Diversi modi di stampare su stdout non sincronizzati). C'è stata una discussione su come apportare queste modifiche, ma anche se tutti dovessero essere d'accordo e la patch fosse scritta domani, non ti aiuterebbe fino a che non avessi aggiornato a qualsiasi versione futura di Python aggiunta a ...

+0

Scusate per il dupe. Guarderò intorno alle risorse che hai fornito. –

+3

@ N-Saba: Beh, è ​​difficile sapere che questo è un dup, perché non è chiaro cosa dovresti cercare finché non conosci già almeno la metà della risposta ... – abarnert

+0

@ N-Saba, so che questo è un vecchio thread, ma dovresti contrassegnarlo come la risposta se rispondeva alla tua domanda (lo ha fatto mia) – ivan7707

0

I set IDLE (Python Shell) e il font predefinito CMD di Windows in Lucida Console (un font supportato da utf-8) e questi tipi di errori sono andati via; e non si vede più scatole [] [] [] [] [] [] [] []

:)

0

@ N-Saba, che cosa è la stringa che causa l'errore di essere gettati? Nel mio caso di test, sembra un bug specifico per la versione in python 2.7.3.

In feed ero l'analisi, il campo "titolo" ha avuto il seguente valore:

u'title': u'Intel\u2019s Sharp-Eyed Social Scientist' 

ho il diritto char apice singolo previsto quando io chiamo uno di questi, in Python 2.7.6 .

python -c "print {u'title': u'Intel\u2019s Sharp-Eyed Social Scientist'}['title']" 
Intel’s Sharp-Eyed Social Scientist 

In 2.7.3, ottengo l'errore, a meno che non codificare il valore che ho tirato da KeyName.

print {u'title': u'Intel\u2019s Sharp-Eyed Social Scientist'}['title'] 
UnicodeEncodeError: 'ascii' codec can't encode character u'\u2019' in position 5: ordinal not in range(128) 
print {u'title': u'Intel\u2019s Sharp-Eyed Social Scientist'}['title'].encode('utf-8', 'replace') 
Intel’s Sharp-Eyed Social Scientist 

FWIW, il comando di stampa @abamert ('\ u2019') stampe "9". Penso che il codice previsto fosse print (u '\ u2019').

+0

Il 'u' non è richiesto per Python 3, dato che ha come valore predefinito Unicode. – leewz

+0

Ricevo questo errore in 2.7.6 – user1167442

0

Mi sono imbattuto in un errore simile durante il tentativo di scrivere un'uscita JSON API in un file .cav tramite pd.DataFrame.to_csv() su un'installazione Win di Python 2.7.14.

Specifica della codifica utf-8 fisso il mio processo:

pd.DataFrame.to_csv(filename, encoding='utf-8') 
0

Per chiunque si verifichi questo in MacOS, la risposta di @ abarnert è corretta e sono stato in grado di risolvere il problema mettendo questo nella parte superiore del file di origine incriminato : -

# magic to make everything work in Unicode 
import sys 
reload(sys) 
sys.setdefaultencoding('utf-8') 

Per chiarire, ci si assicura che l'uscita del terminale accetti Unicode correttamente.

Problemi correlati