web-dev-qa-db-fra.com

Pourquoi Python ne parvient-il pas à analyser ces données JSON?

J'ai ce JSON dans un fichier:

{
    "maps": [
        {
            "id": "blabla",
            "iscategorical": "0"
        },
        {
            "id": "blabla",
            "iscategorical": "0"
        }
    ],
    "masks": [
        "id": "valore"
    ],
    "om_points": "value",
    "parameters": [
        "id": "valore"
    ]
}

J'ai écrit ce script pour imprimer toutes les données JSON:

import json
from pprint import pprint

with open('data.json') as f:
    data = json.load(f)

pprint(data)

Ce programme soulève une exception, cependant:

Traceback (most recent call last):
  File "<pyshell#1>", line 5, in <module>
    data = json.load(f)
  File "/usr/lib/python3.5/json/__init__.py", line 319, in loads
    return _default_decoder.decode(s)
  File "/usr/lib/python3.5/json/decoder.py", line 339, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/usr/lib/python3.5/json/decoder.py", line 355, in raw_decode
    obj, end = self.scan_once(s, idx)
json.decoder.JSONDecodeError: Expecting ',' delimiter: line 13 column 13 (char 213)

Comment analyser le JSON et en extraire les valeurs?

1377
michele

Vos données ne sont pas valides JSON format. Vous avez [] alors que vous devriez avoir {}:

  • [] est destiné aux tableaux JSON, appelés list en Python
  • {} concerne les objets JSON, appelés dict en Python.

Voici à quoi devrait ressembler votre fichier JSON:

{
    "maps": [
        {
            "id": "blabla",
            "iscategorical": "0"
        },
        {
            "id": "blabla",
            "iscategorical": "0"
        }
    ],
    "masks": {
        "id": "valore"
    },
    "om_points": "value",
    "parameters": {
        "id": "valore"
    }
}

Ensuite, vous pouvez utiliser votre code:

import json
from pprint import pprint

with open('data.json') as f:
    data = json.load(f)

pprint(data)

Avec les données, vous pouvez maintenant aussi trouver des valeurs comme ceci:

data["maps"][0]["id"]
data["masks"]["id"]
data["om_points"]

Essayez-les et voyez si cela commence à avoir un sens.

2066
Justin Peel

Votre data.json devrait ressembler à ceci:

{
 "maps":[
         {"id":"blabla","iscategorical":"0"},
         {"id":"blabla","iscategorical":"0"}
        ],
"masks":
         {"id":"valore"},
"om_points":"value",
"parameters":
         {"id":"valore"}
}

Votre code devrait être:

import json
from pprint import pprint

with open('data.json') as data_file:    
    data = json.load(data_file)
pprint(data)

Notez que cela ne fonctionne que dans Python 2.6 et supérieur, car cela dépend de l'instruction with- . Dans Python 2.5, utilisez from __future__ import with_statement, dans Python <= 2.4, voir réponse de Justin Peel , sur laquelle cette réponse est basée.

Vous pouvez maintenant aussi accéder à des valeurs uniques comme ceci:

data["maps"][0]["id"]  # will return 'blabla'
data["masks"]["id"]    # will return 'valore'
data["om_points"]      # will return 'value'
303
Bengt

La réponse de Justin Peel est vraiment utile, mais si vous utilisez Python 3, la lecture de JSON doit se faire comme suit:

with open('data.json', encoding='utf-8') as data_file:
    data = json.loads(data_file.read())

Remarque: utilisez json.loads au lieu de json.load. Dans Python 3, json.loads prend un paramètre de chaîne. json.load prend un paramètre d'objet de type fichier. data_file.read() renvoie un objet chaîne.

Pour être honnête, je ne pense pas que le fait de charger toutes les données JSON en mémoire dans la plupart des cas ne pose pas de problème.

64
Geng Jiawen
data = []
with codecs.open('d:\output.txt','rU','utf-8') as f:
    for line in f:
       data.append(json.loads(line))
53
user1743724

"Ultra JSON" ou simplement "ujson" peut gérer le fait d'avoir [] dans votre entrée de fichier JSON. Si vous lisez un fichier d'entrée JSON dans votre programme en tant que liste d'éléments JSON; tels que [{[{}]}, {}, [], etc...] ujson peut gérer n’importe quel ordre de listes de dictionnaires, dictionnaires de listes.

Vous pouvez trouver ujson dans le index du package Python et l'API est presque identique à la bibliothèque intégrée de Python json.

ujson est également beaucoup plus rapide si vous chargez des fichiers JSON plus volumineux. Vous pouvez voir les détails des performances par rapport aux autres bibliothèques JSON Python dans le même lien que celui fourni.

13
moeabdol

Si vous utilisez Python3, vous pouvez essayer de modifier votre fichier JSON (connection.json) en:

{
  "connection1": {
    "DSN": "con1",
    "UID": "abc",
    "PWD": "1234",
    "connection_string_python":"test1"
  }
  ,
  "connection2": {
    "DSN": "con2",
    "UID": "def",
    "PWD": "1234"
  }
}

Ensuite, en utilisant le code suivant:

connection_file = open('connection.json', 'r')
conn_string = json.load(connection_file)
conn_string['connection1']['connection_string_python'])
connection_file.close()
>>> test1
7
sushmit

Ici vous allez avec le fichier modifié data.json:

{
    "maps": [
        {
            "id": "blabla",
            "iscategorical": "0"
        },
        {
            "id": "blabla",
            "iscategorical": "0"
        }
    ],
    "masks": [{
        "id": "valore"
    }],
    "om_points": "value",
    "parameters": [{
        "id": "valore"
    }]
}

Vous pouvez appeler ou imprimer des données sur la console en utilisant les lignes ci-dessous:

import json
from pprint import pprint
with open('data.json') as data_file:
    data_item = json.load(data_file)
pprint(data_item)

Sortie attendue pour print(data_item['parameters'][0]['id']):

{'maps': [{'id': 'blabla', 'iscategorical': '0'},
          {'id': 'blabla', 'iscategorical': '0'}],
 'masks': [{'id': 'valore'}],
 'om_points': 'value',
 'parameters': [{'id': 'valore'}]}

Sortie attendue pour print(data_item['parameters'][0]['id']):

valore
6
JoboFive

Il y a deux types dans cette analyse.

  1. Analyser les données d'un fichier à partir d'un chemin système
  2. Analyse JSON à partir d'une URL distante.

A partir d'un fichier, vous pouvez utiliser les éléments suivants

import json
json = json.loads(open('/path/to/file.json').read())
value = json['key']
print json['value']

Cet article explique l'analyse complète et l'obtention des valeurs à l'aide de deux scénarios . Analyse de JSON avec Python

5
Bibin Wilson

En tant qu'utilisateur python3 ,

La différence entre les méthodes load et loads est importante, en particulier lorsque vous lisez des données JSON à partir d'un fichier.

Comme indiqué dans la documentation:

json.load:

Désérialisez fp (un fichier texte ou un fichier binaire contenant un document JSON .read ()) en un objet Python à l'aide de cette table de conversion.

json.loads:

json.loads: Deserialize s (une instance str, bytes ou bytearray contenant un document JSON) en un objet Python à l'aide de cette table de conversion.

la méthode json.load peut lire directement le document json ouvert car elle est capable de lire un fichier binaire.

with open('./recipes.json') as data:
  all_recipes = json.load(data)

Par conséquent, vos données JSON sont disponibles dans un format spécifié conformément à cette table de conversion:

https://docs.python.org/3.7/library/json.html#json-to-py-table

4
muratgozel