2015-12-25 7 views
5

Ich versuche, eine JSON-Multiline-Datei unter Verwendung der json-Bibliothek in Python 2.7 zu analysieren. Eine vereinfachte Beispieldatei ist unten angegeben:Problem beim Analysieren einer mehrzeiligen JSON-Datei mit 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" 
     } 
    ] 
} 
} 

Mein Code ist wie folgt:

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 

Trotzdem bekomme ich einen Fehler wie unten dargestellt:

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) 

nur einige Tests zu tun Ich habe den Code so geändert, dass ich nach dem Entfernen von Zeilenumbrüchen und dem Entfernen der führenden und nachfolgenden Leerstellen den Inhalt in eine andere Datei (mit der Erweiterung json) schreibe. Überraschenderweise bekomme ich beim Lesen der letzten Datei keinen Fehler und das Parsen ist erfolgreich. Der modifizierte Code ist wie folgt:

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 

Die Ausgabe ist wie folgt:

{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'}]}} 

Jede Idee, was gehen könnte, wenn neue Linien und weißen Flächen vor der Verwendung json Bibliothek abgezogen werden?

Antwort

4

Sie verrückt gehen, wenn Sie versuchen, eine JSON-Datei Zeile für Zeile zu analysieren. Das json-Modul hat Hilfsmethoden, um Dateiobjekte direkt oder Zeichenketten zu lesen, d. H. Die load und loads Methoden. load nimmt ein Dateiobjekt (wie unten gezeigt) für eine Datei, die JSON-Daten enthält, während loads eine Zeichenfolge verwendet, die JSON-Daten enthält.

Option 1: - Bevorzugte

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

Option 2:

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

Wenn Sie für eine höhere Leistung json Parsing suchen Besuche ujson

+1

Danke @OkezieE. Das Laden der gesamten Datei über 'load' macht den Trick. – hypersonics

5

Im ersten Snippet versuchen Sie, es Zeile für Zeile zu analysieren. Sie sollten alles auf einmal analysieren. Am einfachsten ist es, json.load(jsonfile) zu verwenden. (Der Name der jf-Variablen ist irreführend, da es sich um eine Zeichenfolge handelt). So ist der richtige Weg, es zu analysieren:

import json 

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

Obwohl es eine gute Idee, in einem die json speichern Linie, wie es prägnanter ist.

Im zweiten Schnipsel Ihr Problem ist, dass Sie es als Unicode-String drucken, das ist und u'string here' ist Python-spezifisch. Eine gültige Json verwendet doppelte Anführungszeichen

+0

Ich habe versucht, Ihren Ansatz die von Laden ganze Datei und Parser auf einmal, aber es schlägt fehl. By the way, ich habe versucht, json-Dateien Zeile für Zeile früher ohne Probleme zu analysieren, erwarten, dass jedes Wörterbuch nie über 100 Zeichen lang überschritten. – hypersonics

+0

Für mich funktionierte es gut mit dem von Ihnen bereitgestellten JSON.Versuchen Sie es mit dem Sublime JSON-Plugin, um den JSON zu konvertieren: https://github.com/dzhibas/SublimePrettyJson Es validiert auch den JSON, so dass Sie das Problem weiter untersuchen können. Für detailliertere Lint versuchen http://jsonlint.com/ – fodma1

1

FYI, können Sie beide Dateien in einzelne with Anweisung geöffnet:

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

Während dieser Code die Frage beantworten kann, ist es besser zu erklären, was es tut, und fügen Sie einige Verweise darauf hinzu. – dotctor

+1

Dies bietet keine Antwort auf die Frage. Um einen Autor zu kritisieren oder um Klärung zu bitten, hinterlasse einen Kommentar unter seinem Beitrag. - [Aus Bewertung] (/ review/low-quality-posts/10682568) –

+0

@James: einverstanden. im Moment der Beantwortung konnte ich keine Fragen kommentieren und dank upvote kann ich jetzt :-) –