2015-12-25 15 views
5

Sto provando ad analizzare un file multilinea JSON usando la libreria json in Python 2.7. Un file di esempio semplificato è il seguente:Issue parsing di file JSON multilinea usando Python

{ 
"observations": { 
    "notice": [ 
     { 
      "copyright": "Copyright Commonwealth of Australia 2015, Bureau of Meteorology. For more information see: http://www.bom.gov.au/other/copyright.shtml http://www.bom.gov.au/other/disclaimer.shtml", 
      "copyright_url": "http://www.bom.gov.au/other/copyright.shtml", 
      "disclaimer_url": "http://www.bom.gov.au/other/disclaimer.shtml", 
      "feedback_url": "http://www.bom.gov.au/other/feedback" 
     } 
    ] 
} 
} 

Il mio codice è il seguente:

import json 

with open('test.json', 'r') as jsonFile: 
    for jf in jsonFile: 
     jf = jf.replace('\n', '') 
     jf = jf.strip() 
     weatherData = json.loads(jf) 
     print weatherData 

Tuttavia, ottengo un errore come illustrato di seguito:

Traceback (most recent call last): 
File "test.py", line 8, in <module> 
weatherData = json.loads(jf) 
File "/home/usr/anaconda2/lib/python2.7/json/__init__.py", line 339, in loads 
return _default_decoder.decode(s) 
File "/home/usr/anaconda2/lib/python2.7/json/decoder.py", line 364, in decode 
obj, end = self.raw_decode(s, idx=_w(s, 0).end()) 
File "/home/usr/anaconda2/lib/python2.7/json/decoder.py", line 380, in raw_decode 
obj, end = self.scan_once(s, idx) 
ValueError: Expecting object: line 1 column 1 (char 0) 

solo per fare alcuni test , Ho modificato il codice in modo tale che dopo aver rimosso le nuove righe e aver staccato gli spazi bianchi iniziali e finali, scrivo il contenuto in un altro file (con l'estensione json). Sorprendentemente, quando rileggo il secondo file, non ottengo alcun errore e l'analisi ha esito positivo. Il codice modificato è il seguente:

import json 

filewrite = open('out.json', 'w+') 

with open('test.json', 'r') as jsonFile: 
    for jf in jsonFile: 
     jf = jf.replace('\n', '') 
     jf = jf.strip() 
     filewrite.write(jf) 

filewrite.close() 

with open('out.json', 'r') as newJsonFile: 
    for line in newJsonFile: 
     weatherData = json.loads(line) 
     print weatherData 

L'uscita è la seguente:

{u'observations': {u'notice': [{u'copyright_url': u'http://www.bom.gov.au/other/copyright.shtml', u'disclaimer_url': u'http://www.bom.gov.au/other/disclaimer.shtml', u'copyright': u'Copyright Commonwealth of Australia 2015, Bureau of Meteorology. For more information see: http://www.bom.gov.au/other/copyright.shtml http://www.bom.gov.au/other/disclaimer.shtml', u'feedback_url': u'http://www.bom.gov.au/other/feedback'}]}} 

Qualsiasi idea di quello che potrebbe essere succedendo quando nuove linee e spazi bianchi sono spogliato prima di utilizzare json biblioteca?

risposta

4

Andrete pazza se si tenta di analizzare un file riga per riga JSON. Il modulo json ha metodi di supporto per leggere direttamente gli oggetti file o stringhe, ad esempio i metodi load e loads. load prende un oggetto file (come mostrato di seguito) per un file che contiene dati json, mentre loads accetta una stringa che contiene dati json.

Opzione 1: - preferita

import json 
with open('test.json', 'r') as jf: 
    weatherData = json.load(jf) 
    print weatherData 

Opzione 2:

import json 
with open('test.json', 'r') as jf: 
    weatherData = json.loads(jf.read()) 
    print weatherData 

Se siete alla ricerca di più alto JSON parsing prestazioni controllare ujson

+1

Grazie @OkezieE. Caricare l'intero file tramite 'load' fa il trucco. – hypersonics

5

Nel primo frammento, si tenta di analizzarlo riga per riga. Dovresti analizzare tutto in una volta. Il modo più semplice è usare json.load(jsonfile). (Il nome della variabile jf è fuorviante in quanto è una stringa). Quindi il modo corretto per analizzarlo:

import json 

with open('test.json', 'r') as jsonFile: 
    weatherData = json.loads(jsonFile) 

Anche se è una buona idea per memorizzare il JSON in una linea, come è più conciso.

Nel secondo frammento il problema è che lo si stampa come stringa unicode che è e u'string here' è specifico per Python. Un JSON valido usa le virgolette doppie

+0

Ho cercato il tuo approccio di caricamento del intero file e analisi di tutto in una volta, ma fallisce. A proposito, ho provato ad analizzare i file JSON prima riga per riga senza problemi, aspettandomi che ogni dizionario non superasse mai i 100 caratteri. – hypersonics

+0

Per me funzionava bene con il codice che hai fornito.Prova a utilizzare il plug-in JSON di Sublime per convertire il json avanti e indietro: https://github.com/dzhibas/SublimePrettyJson. Convalida anche il json, in modo da poter esaminare ulteriormente il problema. Per ulteriori informazioni sul linting, provare http://jsonlint.com/ – fodma1

1

FYI, è possibile avere entrambi i file aperti in sola with dichiarazione:

with open('file_A') as in_, open('file_B', 'w+') as out_: 
    # logic here 
    ... 
+0

Sebbene questo codice possa rispondere alla domanda, è meglio spiegare cosa fa e aggiungere alcuni riferimenti ad esso. – dotctor

+1

Questo non fornisce una risposta alla domanda. Per criticare o richiedere chiarimenti da un autore, lascia un commento sotto il loro post. - [Dalla recensione] (/ recensione/post di bassa qualità/10682568) –

+0

@James: concordato. al momento della risposta non sono stato in grado di commentare le domande e grazie a upvote ora posso :-) –