Solución:
Dado que el fragmento proporcionado se parece más a un conjunto de líneas, cada una de las cuales compone un JSON independiente, debe analizarse en consecuencia:
# each JSON is small, there's no need in iterative processing
import json
with open(filename, 'r') as f:
for line in f:
data = json.loads(line)
# data[u'name'], data[u'engine_speed'], data[u'timestamp'] now
# contain correspoding values
Desafortunadamente, la biblioteca ijson (v2.3 a partir de marzo de 2018) no maneja el análisis de múltiples objetos JSON. Solo puede manejar 1 objeto en general, y si intenta analizar un segundo objeto, obtendrá un error: "ijson.common.JSONError: Additional data"
. Vea los informes de errores aquí:
- https://github.com/isagalaev/ijson/issues/40
- https://github.com/isagalaev/ijson/issues/42
- https://github.com/isagalaev/ijson/issues/67
- Python: ¿cómo analizo un flujo de matrices json con la biblioteca ijson?
Es una gran limitación. Sin embargo, siempre que tenga saltos de línea (carácter de nueva línea) después de cada objeto JSON, puede analizar cada uno línea por línea independientemente, como esto:
import io
import ijson
with open(filename, encoding="UTF-8") as json_file:
cursor = 0
for line_number, line in enumerate(json_file):
print ("Processing line", line_number + 1,"at cursor index:", cursor)
line_as_file = io.StringIO(line)
# Use a new parser for each line
json_parser = ijson.parse(line_as_file)
for prefix, type, value in json_parser:
print ("prefix=",prefix, "type=",type, "value=",value)
cursor += len(line)
Todavía está transmitiendo el archivo y no lo está cargando por completo en la memoria, por lo que puede funcionar en archivos JSON grandes. También utiliza la técnica de transmisión de líneas de: ¿Cómo saltar a una línea en particular en un archivo de texto enorme? y usos enumerate()
from: ¿Accediendo al índice en bucles ‘for’?