¿Por qué Python no puede analizar estos datos JSON?

Tengo este JSON en un archivo:

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

Escribí este script para imprimir todos los datos JSON:

import json
from pprint import pprint

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

pprint(data)

Sin embargo, este programa genera una excepción:

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)

¿Cómo puedo analizar el JSON y extraer sus valores?

preguntado el 14 de mayo de 10 a las 12:05

@kederrac Por la razón dada: "Esta pregunta fue causada por un error tipográfico o un problema que ya no se puede reproducir". El json no es válido. -

@kederrac El problema se debe a un error de uso, no a que se pueda reproducir. -

9 Respuestas

Tus datos no son validos JSON formato. Tu tienes [] cuando deberías tener {}:

  • [] son para matrices JSON, que se denominan list en Python
  • {} son para objetos JSON, que se llaman dict en Python

Así es como debería verse su archivo JSON:

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

Entonces puedes usar tu código:

import json
from pprint import pprint

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

pprint(data)

Con datos, ahora también puede encontrar valores como este:

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

Pruébelos y vea si comienza a tener sentido.

respondido 21 mar '19, 21:03

Ok, tengo que controlar mi código porque este archivo json se genera a partir de un objeto java. Gracias. - Michele

Gracias por la solucion Recibo un símbolo Unicode mientras lo imprimo. (por ejemplo, u'valore '). ¿Cómo prevenirlo? - agenda

Agradable pero Python agrega un u' antes de cada tecla. ¿Alguna idea de por qué? - CodyBugstein

Es por eso que su texto es tipo Unicode, no cadena. La mayoría de las veces es mejor tener texto en Unicode para diéresis en alemán y para compartir resultados de texto con otros módulos / programas, etc. ¡Así que estás bien! - Michael P

Me gustaría hacer una observación que espero sea útil y definitivamente irónica. Encuentro que el módulo pprint es inferior al módulo json para json de impresión bonita. Si prueba los dos, creo que estará de acuerdo. Para mostrar y depurar mis estructuras de datos json, he estado haciendo: output = json.dumps (data_structure, indent = 2, sort_keys = True) print (salida) Creo que encontrarás el control de sangría, clasificación e inteligente ajuste de línea en el método dumps () para que sea de su agrado. Si mi forma de pensar es incorrecta, alguien hágamelo saber. - larold

Tus data.json Debe verse así:

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

Tu código debe ser:

import json
from pprint import pprint

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

Tenga en cuenta que esto solo funciona en Python 2.6 y versiones posteriores, ya que depende de la with-declaración. En Python 2.5 uso from __future__ import with_statement, en Python <= 2.4, consulte La respuesta de Justin Peel, en el que se basa esta respuesta.

Ahora también puede acceder a valores individuales como este:

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

contestado el 23 de mayo de 17 a las 13:05

Tengo un voto negativo sobre esto. Quizás no estaba claro por qué pensé que era necesaria otra respuesta. Se agregó una nota sobre la compatibilidad de la declaración with. - Bengt

Perdón por la reversión, pero el código sugerido se mantendría data_file opened más de lo necesario. - Bengt

Consultando la documentación 2.6 (docs.python.org/2.6/library/io.html), abrir un archivo en el contexto "con" cerrará automáticamente el archivo. - Steve S.

@SteveS. Sí, pero no antes de dejar el contexto. pprinting en el with-context mantiene el data_file abrir más tiempo. - Bengt

@GayanPathirage accedes a él como data["om_points"] , data["masks"]["id"]. La idea es que puede alcanzar cualquier nivel en un diccionario especificando las 'rutas clave'. Si obtienes un KeyError excepción significa que la clave no existe en la ruta. Busque errores tipográficos o compruebe la estructura de su diccionario. - nuhman

La respuesta de Justin Peel es realmente útil, pero si está utilizando Python 3, la lectura de JSON debe hacerse así:

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

Nota: use json.loads en lugar de json.load. En Python 3, json.loads toma un parámetro de cadena. json.load toma un parámetro de objeto similar a un archivo. data_file.read() devuelve un objeto de cadena.

Para ser honesto, no creo que sea un problema cargar todos los datos json en la memoria en la mayoría de los casos. Veo esto en JS, Java, Kotlin, cpp, oxida casi todos los lenguajes que uso. Considere el problema de la memoria como una broma para mí :)

Por otro lado, no creo que pueda analizar json sin leerlo todo.

Respondido el 06 de enero de 21 a las 03:01

Porque deberia json.load ser evitado a favor de .loads en Python 3? - Zearín

La página que vinculó no dice nada sobre cómo evitar load. - dan hulme

Esta respuesta lee el archivo completo en la memoria cuando no es necesario y sugiere que en Python 3 los archivos JSON no se pueden leer con pereza, lo cual no es cierto. Lo siento, pero es un voto negativo claro. - Łukasz Rogalski

Esta respuesta no es precisa. No hay razón para no usar json.load con un controlador de archivos abierto en python3. Perdón por el voto negativo, pero no parece que hayas leído los comentarios anteriores con mucha atención. - caminante del anochecer

+1 ¡Esta respuesta es genial! Gracias por eso y me sacó de ir muy lejos por buscar una función que pueda usar cadenas porque solo trabajo con cadenas y solicitudes de red que no son archivos. - gente nueva

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

contestado el 12 de mayo de 13 a las 21:05

esta es la solución correcta si tiene varios objetos json en un archivo. json.loads no decodifica múltiples objetos json. De lo contrario, obtendrá el error "Datos adicionales". - yasin_alm

Esta es la mejor respuesta. De lo contrario, da el error "Datos adicionales". - Tierrax9

Tener varios objetos json en un archivo significa que el archivo en sí no es un json válido. Si tiene varios objetos para incluir en un archivo json, deben estar contenidos en una matriz en el nivel superior del archivo. - caminante del anochecer

Tener varios objetos json en un archivo significa que el archivo no es un solo objeto json. Eso es algo obvio. Hacer una única matriz a partir de los objetos es una solución obvia. Pero JSON está terminado explícitamente por diseño, en casi todos los niveles (por }, ] or "). Por lo tanto, puede concatenar varios objetos en una sola cadena o un solo archivo, sin ambigüedad. El problema aquí es que un analizador que espera un solo objeto falla cuando se le pasa más de un objeto. - MSalters

Anuncio que almacena varios objetos JSON en un solo archivo: hay un "estándar" para eso: jsonlines.org/ejemplos in .jsonl (líneas json), los objetos están separados por un carácter de nueva línea que hace que el preprocesamiento para el análisis sea trivial y permite dividir / lotes fácilmente archivos sin preocuparse por los marcadores de inicio / fin. - Sebi

"Ultra JSON" o simplemente "ujson" pueden manejar tener [] en la entrada de su archivo JSON. Si está leyendo un archivo de entrada JSON en su programa como una lista de elementos JSON; como, [{[{}]}, {}, [], etc...] ujson puede manejar cualquier orden arbitrario de listas de diccionarios, diccionarios de listas.

Puedes encontrar ujson en el Índice de paquetes de Python y la API es casi idéntica a la incorporada de Python json biblioteca.

ujson también es mucho más rápido si está cargando archivos JSON más grandes. Puede ver los detalles de rendimiento en comparación con otras bibliotecas JSON de Python en el mismo enlace proporcionado.

Respondido 10 Feb 18, 04:02

Si está utilizando Python3, puede intentar cambiar su (connection.json archivo) JSON a:

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

Luego usando el siguiente código:

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

Respondido 13 Abr '19, 10:04

esto deja abierto el identificador del archivo. usando un with declaración sería mejor - corey goldberg

Hay dos tipos en este análisis.

  1. Analizar datos de un archivo de una ruta del sistema
  2. Analizando JSON desde una URL remota.

Desde un archivo, puede usar lo siguiente

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

Este artículo explica el análisis completo y la obtención de valores utilizando dos escenarios.Analizando JSON usando Python

Respondido 05 Oct 18, 14:10

¡Muchas gracias por el método "analizar datos de un archivo en el sistema"! - JackR

Aquí tienes modificado data.json archivo:

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

Puede llamar o imprimir datos en la consola usando las siguientes líneas:

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

Salida esperada para print(data_item['parameters'][0]['id']):

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

Salida esperada para print(data_item['parameters'][0]['id']):

valore

Respondido 13 Abr '19, 10:04

Si quisiéramos agregar una columna para contar cuántas observaciones tienen los "mapas", ¿cómo podríamos escribir esta función? - Chenxi

Como usuario de python3,

La diferencia entre los load y loads Los métodos son importantes especialmente cuando lee datos json desde el archivo.

Como se indica en los documentos:

json.cargar:

Deserializar fp (un .read () - archivo de texto de soporte o archivo binario que contiene un documento JSON) a un objeto Python usando esta tabla de conversión.

json.loads:

json.loads: Deserialize s (una instancia de str, bytes o bytearray que contiene un documento JSON) a un objeto Python usando esta tabla de conversión.

El método json.load puede leer directamente el documento json abierto, ya que puede leer archivos binarios.

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

Como resultado, sus datos json están disponibles en un formato especificado de acuerdo con esta tabla de conversión:

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

respondido 30 nov., 18:09

¿Cómo es esta una respuesta a la pregunta formulada? El usuario estaba usando el método correcto para cargar el archivo json. - Raj006

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.