¿Leyendo JSON de un archivo?

320

Me duele un poco el dolor de cabeza solo porque una declaración simple y fácil me arroja algunos errores en la cara.

Tengo un archivo json llamado strings.json como este:

"strings": [{"-name": "city", "#text": "City"}, {"-name": "phone", "#text": "Phone"}, ...,
            {"-name": "address", "#text": "Address"}]

Quiero leer el archivo json, solo eso por ahora. Tengo estas declaraciones que descubrí, pero no funciona:

import json
from pprint import pprint

with open('strings.json') as json_data:
    d = json.loads(json_data)
    json_data.close()
    pprint(d)

El error mostrado en la consola fue este:

Traceback (most recent call last):
  File "/home/.../android/values/manipulate_json.py", line 5, in <module>
    d = json.loads(json_data)
  File "/usr/lib/python2.7/json/__init__.py", line 326, in loads
    return _default_decoder.decode(s)
  File "/usr/lib/python2.7/json/decoder.py", line 366, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
TypeError: expected string or buffer
[Finished in 0.1s with exit code 1]

Editado

Cambiado de json.loadsajson.load

y obtuve esto:

Traceback (most recent call last):
  File "/home/.../android/values/manipulate_json.py", line 5, in <module>
    d = json.load(json_data)
  File "/usr/lib/python2.7/json/__init__.py", line 278, in load
    **kw)
  File "/usr/lib/python2.7/json/__init__.py", line 326, in loads
    return _default_decoder.decode(s)
  File "/usr/lib/python2.7/json/decoder.py", line 369, in decode
    raise ValueError(errmsg("Extra data", s, end, len(s)))
ValueError: Extra data: line 829 column 1 - line 829 column 2 (char 18476 - 18477)
[Finished in 0.1s with exit code 1]
CRR
fuente
66
¿Estás seguro de que el archivo contiene JSON válido?
Píldoras de explosión
1
posible duplicado de valores
Pureferret
Ver también: Ejemplo de lectura y escritura para JSON
Martin Thoma
Su archivo tiene un formato json no válido. {"strings": [{"-name": "city", "#text": "City"}, {"-name": "phone", "#text": "Phone"}, ..., {"-name": "address", "#text": "Address"}]}
Cámbielo

Respuestas:

546

El json.load()método (sin "s" en "cargar") puede leer un archivo directamente:

import json

with open('strings.json') as f:
    d = json.load(f)
    print(d)

Estaba utilizando el json.loads()método , que se usa solo para argumentos de cadena .

Editar: El nuevo mensaje es un problema totalmente diferente. En ese caso, hay algunos json no válidos en ese archivo. Para eso, recomendaría ejecutar el archivo a través de un validador json .

También hay soluciones para arreglar json, como por ejemplo ¿Cómo reparo automáticamente una cadena JSON no válida? .

ubomb
fuente
2
hm ... cambié de json.loads a json.load pero obtengo ese buen mensaje.
RRC
55
Ah, bueno, el nuevo mensaje es un problema totalmente diferente. En ese caso, hay algunos json no válidos en ese archivo. Para eso, recomendaría ejecutar el archivo a través de un validador json .
ubomb
3
¡Entendido! Al archivo le faltaba EOF. El archivo no se terminó correctamente. ¡No lo notaría si no fuera tu buena recomendación! ¡Gracias!
RRC
1
ubomb, si puedes cambiar me contestas para marcarlo como aceptado. ¡Se libre! Lo marcaré
RRC
Debo abrir el archivo con un indicador de bytes, entonces puedo usar el método json.load, ¿por qué? Tengo Py3.6
Grzegorz Krug el
113

Aquí hay una copia del código que funciona bien para mí.

import json

with open("test.json") as json_file:
    json_data = json.load(json_file)
    print(json_data)

con los datos

{
    "a": [1,3,"asdf",true],
    "b": {
        "Hello": "world"
    }
}

es posible que desee ajustar su línea json.load con un intento de captura porque JSON no válido causará un mensaje de error stacktrace.

usuario1876508
fuente
41

El problema está usando con la declaración:

with open('strings.json') as json_data:
    d = json.load(json_data)
    pprint(d)

El archivo ya estará implícitamente cerrado. No hay necesidad de llamar json_data.close()nuevamente.

Zongjun
fuente
1
Elimine json_data.close (). Como se mencionó, se llamará implícitamente.
Bonnie Varghese
1
@ Zongjun: Corrija las cargas a json.load (json_data).
Knight71
2
para imprimir bien, tuve que usar:print(json.dumps(d,sort_keys=True,indent=2))
Mike D
25

En python 3, podemos usar el siguiente método.

Leer del archivo y convertir a JSON

import json
from pprint import pprint

# Considering "json_list.json" is a json file

with open('json_list.json') as fd:
     json_data = json.load(fd)
     pprint(json_data)

Con la declaración, se cierra automáticamente el descriptor de archivo abierto.


Cadena a JSON

import json
from pprint import pprint

json_data = json.loads('{"name" : "myName", "age":24}')
pprint(json_data)
Thejesh PR
fuente
1

Puede usar la biblioteca de pandas para leer el archivo JSON.

import pandas as pd
df = pd.read_json('strings.json',lines=True)
print(df)
drorhun
fuente
0

Esto funciona para mi.

json.load () acepta el objeto de archivo, analiza los datos JSON, llena un diccionario de Python con los datos y se los devuelve.

Supongamos que el archivo JSON es así:

{
   "emp_details":[
                 {
                "emp_name":"John",
                "emp_emailId":"[email protected]"  
                  },
                {
                 "emp_name":"Aditya",
                 "emp_emailId":"[email protected]"
                }
              ] 
}

import json 

# Opening JSON file 
f = open('data.json',) 

# returns JSON object as  
# a dictionary 
data = json.load(f) 

# Iterating through the json 
# list 
for i in data['emp_details']: 
    print(i) 

# Closing file 
f.close()

#Output:
{'emp_name':'John','emp_emailId':'[email protected]'}
{'emp_name':'Aditya','emp_emailId':'[email protected]'}
Aditya patil
fuente