¿Cómo analizar JSON en Python?

282

Mi proyecto actualmente está recibiendo un mensaje JSON en Python del cual necesito obtener fragmentos de información. A los efectos de esto, configurémoslo en un JSON simple en una cadena:

jsonStr = '{"one" : "1", "two" : "2", "three" : "3"}'

Hasta ahora he estado generando solicitudes JSON usando una lista y luego json.dumps, pero para hacer lo contrario de esto, creo que necesito usar json.loads. Sin embargo, no he tenido mucha suerte con eso. ¿Podría alguien proporcionarme un fragmento que volvería "2"con la entrada de "two"en el ejemplo anterior?

ingh.am
fuente
8
Nota : Para aquellos que vienen aquí con datos que usan 'delimitadores de cadena de comillas simples, puede haber creado accidentalmente representaciones de cadenas para los diccionarios de Python. JSON siempre usará "delimitadores . Si es así, repare su código que produce esa salida para usar en json.dumps()lugar de str()o repr(), y diríjase a Convertir una representación de cadena de un diccionario en un diccionario. para descubrir cómo recuperar sus datos de Python. ¿Otras pistas tienes un literal de Python? Busque None, Trueo False, JSON usaría null, truey false.
Martijn Pieters
Aquellos que no tienen un jsonStr pero una lista de diccionarios (posiblemente con 'delimitadores de cadena de comillas simples), también echen un vistazo aquí: stackoverflow.com/questions/41168558/…
Lorenz

Respuestas:

493

Muy simple:

import json
data = json.loads('{"one" : "1", "two" : "2", "three" : "3"}')
print data['two']
John Giotta
fuente
Además, eche un vistazo a simplejson si necesita un mejor rendimiento. Las versiones más recientes proporcionan optimizaciones que mejoran en gran medida la lectura y la escritura.
Unode
2
En realidad estoy usando ya simplejson: import simplejson as json. Olvidé mencionarlo pero gracias :)
ingh.am
Entendido. Estaba usando el .loadmétodo en lugar de.loads
Sunil Kumar
85

A veces tu json no es una cadena. Por ejemplo, si obtiene un json de una URL como esta:

j = urllib2.urlopen('http://site.com/data.json')

necesitará usar json.load, no json.loads:

j_obj = json.load(j)

(es fácil de olvidar: la 's' es para 'cadena')

jisaacstone
fuente
Solo para agregar que puede obtener el contenido de la cadena llamando a j.read () y luego usando el método de cargas. De cualquier manera, en este caso, el método load () se encarga de llamar a .read ()
rkachach el
51

Para URL o archivo, use json.load(). Para cadenas con contenido .json, use json.loads().

#! /usr/bin/python

import json
# from pprint import pprint

json_file = 'my_cube.json'
cube = '1'

with open(json_file) as json_data:
    data = json.load(json_data)

# pprint(data)

print "Dimension: ", data['cubes'][cube]['dim']
print "Measures:  ", data['cubes'][cube]['meas']
Mohammad Shahid Siddiqui
fuente
26

El siguiente es un ejemplo simple que puede ayudarlo:

json_string = """
{
    "pk": 1, 
    "fa": "cc.ee", 
    "fb": {
        "fc": "", 
        "fd_id": "12345"
    }
}"""

import json
data = json.loads(json_string)
if data["fa"] == "cc.ee":
    data["fb"]["new_key"] = "cc.ee was present!"

print json.dumps(data)

La salida para el código anterior será:

{"pk": 1, "fb": {"new_key": "cc.ee was present!", "fd_id": "12345", 
 "fc": ""}, "fa": "cc.ee"}

Tenga en cuenta que puede configurar el argumento ident de dump para imprimirlo así (por ejemplo, cuando usa print json.dumps (data, indent = 4)):

{
    "pk": 1, 
    "fb": {
        "new_key": "cc.ee was present!", 
        "fd_id": "12345", 
        "fc": ""
    }, 
    "fa": "cc.ee"
}
Venkat
fuente
-2

Puede usar módulos json o ast python:

Using json :
=============

import json
jsonStr = '{"one" : "1", "two" : "2", "three" : "3"}'
json_data = json.loads(jsonStr)
print(f"json_data: {json_data}")
print(f"json_data['two']: {json_data['two']}")

Output:
json_data: {'one': '1', 'two': '2', 'three': '3'}
json_data['two']: 2




Using ast:
==========

import ast
jsonStr = '{"one" : "1", "two" : "2", "three" : "3"}'
json_dict = ast.literal_eval(jsonStr)
print(f"json_dict: {json_dict}")
print(f"json_dict['two']: {json_dict['two']}")

Output:
json_dict: {'one': '1', 'two': '2', 'three': '3'}
json_dict['two']: 2
Biranchi
fuente
1
No puede usar la ast.literal_eval()función para JSON, porque más allá de sus ejemplos triviales de solo texto y enteros, se encontrará con problemas. JSON no es Python . El hecho de que algunos JSON se puedan analizar ast.literal_eval()no hace que sea un enfoque adecuado.
Martijn Pieters
1
Por ejemplo, no puede analizar r'{"foo": null, "bar": true, "baz": "\ud83e\udd26"}'usando ast.literal_eval(), porque contiene valores nulos, un valor booleano y un único punto de código no BMP. JSON representa esos valores de manera diferente a cómo los literales de Python los representarían. json.loads()por el contrario, no tiene problemas con eso de entrada y decodifica correctamente que a {'foo': None, 'bar': True, 'baz': '🤦'}.
Martijn Pieters
1
A continuación, ast.literal_eval()es un poco más lento y no se puede personalizar. Nunca debe usarlo para decodificar JSON .
Martijn Pieters