Pretty-Print des données JSON dans un fichier à l'aide de Python

111

Un projet de classe implique l'analyse des données JSON Twitter. J'obtiens les données et je les place dans le fichier sans trop de problèmes, mais tout est sur une seule ligne. C'est bien pour la manipulation de données que j'essaie de faire, mais le fichier est ridiculement difficile à lire et je ne peux pas l'examiner très bien, ce qui rend l'écriture de code pour la partie manipulation de données très difficile.

Est-ce que quelqu'un sait comment faire cela à partir de Python (c'est-à-dire sans utiliser l'outil de ligne de commande, que je ne peux pas faire travailler)? Voici mon code pour l'instant:

header, output = client.request(twitterRequest, method="GET", body=None,
                            headers=None, force_auth_header=True)

# now write output to a file
twitterDataFile = open("twitterData.json", "wb")
# magic happens here to make it pretty-printed
twitterDataFile.write(output)
twitterDataFile.close()

Notez que j'apprécie les gens qui me pointent vers la documentation simplejson et autres, mais comme je l'ai dit, j'ai déjà regardé cela et j'ai encore besoin d'aide. Une réponse vraiment utile sera plus détaillée et explicative que les exemples qui s'y trouvent. Merci

Aussi: Essayer ceci dans la ligne de commande Windows:

more twitterData.json | python -mjson.tool > twitterData-pretty.json

se traduit par ceci:

Invalid control character at: line 1 column 65535 (char 65535)

Je vous donnerais les données que j'utilise, mais elles sont très volumineuses et vous avez déjà vu le code que j'ai utilisé pour créer le fichier.

Zelbinian
la source
1
Je doute que vous vouliez réellement écrire des données binaires ("wb")
Hamish
On m'a appris que c'était nécessaire pour les machines Windows et jusqu'à présent, j'ai travaillé pour toutes mes missions. Si vous pouvez fournir une documentation expliquant pourquoi cela pourrait être incorrect, je serais heureux de l'examiner.
Zelbinian
Ce n'est nécessaire que si vous travaillez avec des fichiers binaires, ou dans d'autres cas où la forme spécifique de fin de ligne (par exemple \r\nvs \n) est importante. Voir stackoverflow.com/questions/3257869/… . Dans votre cas, vous voulez des fins de ligne conviviales pour Windows, mais vous pourriez ne pas l'obtenir à partir du point de terminaison Twitter, vous devez donc ouvrir en mode texte.
Hamish
Est-ce que cela répond à votre question? Comment imprimer un fichier JSON?
wesinat0r

Réponses:

102

Vous devez utiliser l'argument facultatif indent.

header, output = client.request(twitterRequest, method="GET", body=None,
                            headers=None, force_auth_header=True)

# now write output to a file
twitterDataFile = open("twitterData.json", "w")
# magic happens here to make it pretty-printed
twitterDataFile.write(simplejson.dumps(simplejson.loads(output), indent=4, sort_keys=True))
twitterDataFile.close()
Mattbornski
la source
1
Merci, cela a parfaitement fonctionné . Pouvez-vous expliquer pourquoi "sort_keys" doit être là?
Zelbinian
1
Il n'a pas besoin d'être là, mais cela rend les choses très jolies et classées par ordre alphabétique. J'ai tendance à l'utiliser lorsque je veux une sortie lisible par l'homme.
mattbornski
4
Bien expliqué merci - cependant, ne pas essayer d'être un & $ & # mais ouvrir / fermer pour écrire un fichier n'est pas encourageant, la structure avec est généralement préférable: l' with open("name_of_file.json", "w") as f: f.write(my_formatted_json_var) avantage étant que vous êtes sûr que le fichier se fermera, par exemple sur de plus gros extraits ...
logicOnAbstractions
withla syntaxe est certainement plus agréable, mais j'essaie d'
adapter
73

Vous pouvez analyser le JSON, puis le renvoyer avec des retraits comme ceci:

import json
mydata = json.loads(output)
print json.dumps(mydata, indent=4)

Voir http://docs.python.org/library/json.html pour plus d'informations.

dkamins
la source
@Zelbinian: oui , il travaille pour simplejson comme well.Take un coup d' oeil ici simplejson.googlecode.com/svn/tags/simplejson-1.9.1/docs/...
RanRag
Cela entraîne un fichier vide. header, output = client.request(twitterRequest, method="GET", body=None, headers=None, force_auth_header=True) twitterDataFile = open("twitterData.json", "wb") json.dumps(json.loads(output), twitterDataFile, indent=4) twitterDataFile.close()
Zelbinian
5
@Zelbinian - json.dumpsrenvoie une chaîne. json.dumpécrit dans un fichier.
dkamins
65
import json

with open("twitterdata.json", "w") as twitter_data_file:
    json.dump(output, twitter_data_file, indent=4, sort_keys=True)

Vous n'en avez pas besoin json.dumps()si vous ne souhaitez pas analyser la chaîne plus tard, utilisez simplement json.dump(). C'est aussi plus rapide.

Andras Dosztal
la source
14

Vous pouvez utiliser le module json de python pour une jolie impression.

>>> import json
>>> print json.dumps({'4': 5, '6': 7}, sort_keys=True, indent=4)
{
    "4": 5,
    "6": 7
}

Alors, dans ton cas

>>> print json.dumps(json_output, indent=4)
RanRag
la source
J'ai essayé cette voie et cela ne fonctionne malheureusement pas aussi bien que vous le pensez.
Zelbinian
@Zelbinian: Que voulez-vous dire exactement par doesn't work as well.?
RanRag
1
Il a sorti les données sur une seule ligne dans ce qui semblait être la syntaxe Python dict au lieu de la syntaxe Json assez imprimée
Zelbinian
Incluez la sortie dans votre question en tant que modification afin que nous puissions la voir.
RanRag
en utilisant cela, les tableaux sont listés en autant de lignes de chaque valeur, ce serait bien de garder le tableau sur une seule ligne.
scape
4

Si vous avez déjà des fichiers JSON existants que vous souhaitez mettre en forme, vous pouvez utiliser ceci:

    with open('twitterdata.json', 'r+') as f:
        data = json.load(f)
        f.seek(0)
        json.dump(data, f, indent=4)
        f.truncate()
locke14
la source
3

Si vous générez un nouveau fichier * .json ou modifiez un fichier josn existant, utilisez le paramètre "indent" pour le format json de jolie vue.

import json
responseData = json.loads(output)
with open('twitterData.json','w') as twitterDataFile:    
    json.dump(responseData, twitterDataFile, indent=4)
Praveen SN
la source
1
import json
def writeToFile(logData, fileName, openOption="w"):
  file = open(fileName, openOption)
  file.write(json.dumps(json.loads(logData), indent=4)) 
  file.close()  
Peter
la source
Bien que ce code puisse répondre à la question, fournir un contexte supplémentaire concernant la raison et / ou la manière dont ce code répond à la question améliore sa valeur à long terme.
Tân
-2

Vous pouvez rediriger un fichier vers python et l'ouvrir à l'aide de l'outil et pour le lire, utilisez davantage.

L'exemple de code sera,

cat filename.json | python -m json.tool | more
Ramya
la source