2012-02-15 11 views
35

Ho una stringa come questa:Python json.loads non riesce con `ValueError: non valido carattere di controllo in: linea 1 della colonna 33 (char 33)`

s = u"""{"desc": "\u73cd\u54c1\u7f51-\u5168\u7403\u6f6e\u6d41\u5962\u54c1\u7f51\u7edc\u96f6\u552e\u5546 <br \/>\r\nhttp:\/\/www.zhenpin.com\/ <br \/>\r\n<br \/>\r\n200\u591a\u4e2a\u56fd\u9645\u4e00\u7ebf\u54c1\u724c\uff0c\u9876\u7ea7\u4e70\u624b\u5168\u7403\u91c7\u8d2d\uff0c100%\u6b63\u54c1\u4fdd\u969c\uff0c7\u5929\u65e0\u6761\u2026"}""" 

json.loads(s) restituisce messaggio di errore come questo:

ValueError: Invalid control character at: line 1 column 33 (char 33) 

Perché si verifica questo errore? Come posso risolvere questo problema?

+3

possibile duplicato di [json.loads (jsonstring) in Python fallisce se la stringa ha un "\ r", cioè carattere di ritorno a capo] (http://stackoverflow.com/questions/8324169/json-loadsjsonstring-in-python-fails-if-string-has-arie-carriage-return) – Kimvais

risposta

49

Il problema è la stringa unicode contiene ritorni a capo (\r) e ritorni a capo (\n) all'interno una stringa letterale nei dati JSON. Se dovessero essere parte della stringa stessa, dovrebbero essere sfuggiti in modo appropriato. Se non dovevano essere parte della stringa, non dovrebbero neanche essere nel tuo JSON.

Se non è possibile risolvere il problema dove hai preso questa stringa JSON per la produzione di JSON valido, è possibile rimuovere i caratteri incriminati:

>>> json.loads(s.replace('\r\n', '')) 

o fuggire manualmente:

>>> json.loads(s.replace('\r\n', '\\r\\n')) 
7

cercare di sfuggire il tuo \n e \r:

s = s.replace('\r', '\\r').replace('\n', '\\n') 
json.loads(s) 
>>> {u'desc': u'\u73cd\u54c1\u7f51-\u5168\u7403\u6f6e\u6d41\u5962\u54c1\u7f51\u7edc\u96f6\u552e\u5546 <br />\r\nhttp://www.zhenpin.com/ <br />\r\n<br />\r\n200\u591a\u4e2a\u56fd\u9645\u4e00\u7ebf\u54c1\u724c\uff0c\u9876\u7ea7\u4e70\u624b\u5168\u7403\u91c7\u8d2d\uff0c100%\u6b63\u54c1\u4fdd\u969c\uff0c7\u5929\u65e0\u6761\u2026'} 
+0

Questo fa parte di ciò che ho ricevuto dall'API di un altro sito, non so se ci sono altri caratteri non validi. Conosci altri caratteri non validi? –

10

Il problema è che il carattere nell'indice 33 è un carattere di controllo di ritorno a capo.

>>> s[33] 
u'\r' 

Secondo le specifiche JSON, caratteri validi sono:

  • qualsiasi carattere Unicode, tranne: ", \, e controllo-caratteri (ord(char) < 32).

  • Le seguenti sequenze di caratteri sono consentiti: \", \\, \/, \b (backspace), \f (form feed), \n (-avanzamento riga/new-line), \r (ritorno carrello), \t (scheda) oppure \u seguito da quattro cifre esadecimali.

Tuttavia, in Python si sta andando ad avere per caratteri a doppio controllo di fuga (a meno che la stringa è crudo) perché Python interpreta anche quei caratteri di controllo.

>>> s = ur"""{"desc": "\u73cd\u54c1\u7f51-\u5168\u7403\u6f6e\u6d41\u5962\u54c1\u7f51\u7edc\u96f6\u552e\u5546 <br \/>\r\nhttp:\/\/www.zhenpin.com\/ <br \/>\r\n<br \/>\r\n200\u591a\u4e2a\u56fd\u9645\u4e00\u7ebf\u54c1\u724c\uff0c\u9876\u7ea7\u4e70\u624b\u5168\u7403\u91c7\u8d2d\uff0c100%\u6b63\u54c1\u4fdd\u969c\uff0c7\u5929\u65e0\u6761\u2026"}""" 
>>> json.loads(s) 
{u'desc': u'\u73cd\u54c1\u7f51-\u5168\u7403\u6f6e\u6d41\u5962\u54c1\u7f51\u7edc\u96f6\u552e\u5546 <br />\r\nhttp://www.zhenpin.com/ <br />\r\n<br />\r\n200\u591a\u4e2a\u56fd\u9645\u4e00\u7ebf\u54c1\u724c\uff0c\u9876\u7ea7\u4e70\u624b\u5168\u7403\u91c7\u8d2d\uff0c100%\u6b63\u54c1\u4fdd\u969c\uff0c7\u5929\u65e0\u6761\u2026'} 

Riferimenti:

+1

Cosa succede se la stringa si trova in una variabile? Per esempio, sto ricevendo (tramite un POST HTTP) un oggetto JSON come questo: '{" testo ":" Ciao, \ n Come stai? "}'. Ovviamente non posso usare 'r''' per creare una stringa grezza da questo. Come posso chiedere a Python di trattarlo come tale, o è troppo tardi e ora ho bisogno di usare una sorta di sostituzione di stringhe? – orokusaki

+0

@orokusaki Se il JSON che si sta ricevendo ha caratteri di controllo letterale invece delle sequenze di caratteri appropriate, è davvero troppo tardi perché il JSON non è stato generato correttamente. Quindi dovresti fare qualche sostituzione di stringhe in Python se non riesci a controllare la generazione iniziale. – cpburnz

+0

Grazie per la risposta. Ho finito per passare 'strict = False' a' loads', che ritenevo potesse essere una soluzione più pulita - vedremo se tornerà a mordermi:/ – orokusaki

70

Un'altra opzione, forse, è quello di utilizzare il strict=False argomento

Secondo http://docs.python.org/2/library/json.html

"Se rigorosa è FALSE (Vero è il valore predefinito), quindi i caratteri di controllo saranno consentiti all'interno delle stringhe. I caratteri di controllo in questo contesto sono quelli con codici di carattere nel range 0-31, tra cui '\ t' (scheda), '\ n', '\ r' e '\ 0' "

Ad esempio:.

json.loads(json_str, strict=False) 
0

in alcuni casi, questo errore verrà generato quando il file contiene in realtà una stringa con uno spazio bianco in esso. l'eliminazione gli spazi risolverà il problema.

+0

Questo non fornisce una risposta alla domanda. Per criticare o richiedere chiarimenti da un autore, lascia un commento sotto il loro post - puoi sempre commentare i tuoi post, e una volta che hai [reputazione] sufficiente (http://stackoverflow.com/help/whats-reputation) essere in grado di [commentare qualsiasi post] (http://stackoverflow.com/help/privileges/comment). – Mathias

+0

Non posso ancora commentare .... Mi dispiace – sheldonkreger

+0

prova a riscrivere la tua verbosità, che nella sua forma attuale è più adatta per essere un commento, e la prenoto sotto forma di una risposta. Descrivi ciò che ritieni essere il problema e la soluzione consigliata. –

Problemi correlati