Chargement et analyse d'un fichier JSON avec plusieurs objets JSON


101

J'essaye de charger et d'analyser un fichier JSON en Python . Mais je suis bloqué en essayant de charger le fichier:

import json
json_data = open('file')
data = json.load(json_data)

Rendements:

ValueError: Extra data: line 2 column 1 - line 225116 column 1 (char 232 - 160128774)

J'ai regardé 18,2. json- Encodeur et décodeur JSON dans la documentation Python, mais il est assez décourageant de lire cette documentation horrible.

Premières lignes (anonymisées avec des entrées aléatoires):

{"votes": {"funny": 2, "useful": 5, "cool": 1}, "user_id": "harveydennis", "name": "Jasmine Graham", "url": "http://example.org/user_details?userid=harveydennis", "average_stars": 3.5, "review_count": 12, "type": "user"}
{"votes": {"funny": 1, "useful": 2, "cool": 4}, "user_id": "njohnson", "name": "Zachary Ballard", "url": "https://www.example.com/user_details?userid=njohnson", "average_stars": 3.5, "review_count": 12, "type": "user"}
{"votes": {"funny": 1, "useful": 0, "cool": 4}, "user_id": "david06", "name": "Jonathan George", "url": "https://example.com/user_details?userid=david06", "average_stars": 3.5, "review_count": 12, "type": "user"}
{"votes": {"funny": 6, "useful": 5, "cool": 0}, "user_id": "santiagoerika", "name": "Amanda Taylor", "url": "https://www.example.com/user_details?userid=santiagoerika", "average_stars": 3.5, "review_count": 12, "type": "user"}
{"votes": {"funny": 1, "useful": 8, "cool": 2}, "user_id": "rodriguezdennis", "name": "Jennifer Roach", "url": "http://www.example.com/user_details?userid=rodriguezdennis", "average_stars": 3.5, "review_count": 12, "type": "user"}

Réponses:


222

Vous disposez d'un fichier texte au format JSON Lines . Vous devez analyser votre fichier ligne par ligne:

import json

data = []
with open('file') as f:
    for line in f:
        data.append(json.loads(line))

Chaque ligne contient du JSON valide, mais dans son ensemble, ce n'est pas une valeur JSON valide car il n'y a pas de liste de niveau supérieur ou de définition d'objet.

Notez que parce que le fichier contient du JSON par ligne, vous évitez les maux de tête d'essayer de tout analyser en une seule fois ou de trouver un analyseur JSON en streaming. Vous pouvez maintenant choisir de traiter chaque ligne séparément avant de passer à la suivante, en économisant de la mémoire dans le processus. Vous ne voulez probablement pas ajouter chaque résultat à une liste, puis tout traiter si votre fichier est vraiment volumineux.

Si vous avez un fichier contenant des objets JSON individuels avec des délimiteurs entre les deux, utilisez Comment utiliser le module 'json' pour lire un objet JSON à la fois? pour analyser des objets individuels à l'aide d'une méthode tamponnée.


2
+1 Peut-être qu'il vaut la peine de noter que si vous n'avez pas besoin de tous les objets à la fois, les traiter un par un peut être une approche plus efficace. De cette façon, vous n'aurez pas besoin de stocker des données entières dans la mémoire, mais une seule partie de celles-ci.
Tadeck

1
@Pi_: vous aurez un dictionnaire, alors accédez simplement aux champs sous forme de clés:data = json.loads(line); print data[u'votes']
Martijn Pieters

1
@Pi_: affichez ensuite le résultat de json.loads () ou utilisez le débogueur pour inspecter.
Martijn Pieters

1
@Pi_: non; ne confondez pas le format JSON avec la représentation python dict. Vous voyez maintenant des dictionnaires python avec des chaînes.
Martijn Pieters

1
@ user2441441: voir la réponse liée du message ici.
Martijn Pieters


4

C'est mal formaté. Vous avez un objet JSON par ligne, mais ils ne sont pas contenus dans une structure de données plus grande (c'est-à-dire un tableau). Vous devrez soit le reformater pour qu'il commence par [et se termine par ]une virgule à la fin de chaque ligne, soit l'analyser ligne par ligne comme des dictionnaires distincts.


20
Avec un fichier de 50 Mo, l'OP est probablement mieux de traiter les données ligne par ligne de toute façon. :-)
Martijn Pieters

11
Le fait que le fichier soit mal formaté dépend de son point de vue. S'il était destiné à être au format "lignes JSON", il est valide. Voir: jsonlines.org
LS
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.