Analizar e imprimir datos JSON usando Python

Soy nuevo en JSON y estoy trabajando en la extracción de valores de los datos JSON utilizando Python. Estoy obteniendo los datos JSON usando otro script de shell con cURL.

Aquí está mi salida JSON del script de shell (llamado test.sh):

{"preview":true,"offset":0,"result":{"Country":"AU","count":"417"}} {"preview":true,"offset":1,"result":{"Country":"BG","count":"7"}} {"preview":true,"offset":2,"result":{"Country":"CA","count":"198"}} {"preview":true,"offset":3,"result":{"Country":"CH","count":"1"}} {"preview":true,"offset":4,"result":{"Country":"CN","count":"3"}} {"preview":true,"offset":5,"result":{"Country":"CR","count":"1"}} {"preview":true,"offset":6,"result":{"Country":"DE","count":"148"}} {"preview":true,"offset":7,"result":{"Country":"DK","count":"1"}} {"preview":true,"offset":8,"result":{"Country":"FI","count":"1"}} {"preview":true,"offset":9,"result":{"Country":"FR","count":"1052"}} {"preview":true,"offset":10,"result":{"Country":"GB","count":"1430"}} {"preview":true,"offset":11,"result":{"Country":"HK","count":"243"}} {"preview":false,"offset":12,"lastrow":true,"result":{"Country":"VG","count":"54"}} 

Quiero imprimir todos los valores de “País” y los valores de “recuento” en algo como esto:

 AU 417 BG 7 CA 198 ... 

Para hacerlo, creé un bucle para buscar e imprimir todos los valores necesarios, pero recibo este error:

  AttributeError: 'str' object has no attribute 'read' 

Este es mi código python:

 import subprocess import json import sys import subprocess answer = subprocess.check_output(['./test.sh']) #test.sh contains the cURL command json_obj = json.load(answer) for i in json_obj['result']: print i['Country'] print i['count'] 

Me estoy perdiendo de algo ?

Cualquier ayuda sería apreciada, muchas gracias.

Guarde el código en test.py y los datos en test.json .

test.py

 import json with open('/tmp/test.json') as f: for i in f: data = json.loads(i) print("{Country} {count}".format(**data["result"])) 

prueba.json

 $ python test.py AU 417 BG 7 CA 198 CH 1 CN 3 CR 1 DE 148 DK 1 FI 1 FR 1052 GB 1430 HK 243 VG 54 

También puedes probarlo en tu prog:

 for i in answer: data = json.loads(i) print("{Country} {count}".format(**data["result"])) 

Veo varias cosas mal o mal interpretadas en el post:

  1. Si tiene una colección de objetos JSON, debe convertirlos en una matriz de objetos, o analizarlos uno a la vez como archivos separados o líneas separadas en un archivo (no recomendado). Lo primero sería más fácil y más confiable:

     [{"obj":1},{"obj":2},...] 
  2. Debería usar json.loads y no json.load si está cargando directamente desde una cadena y no desde un archivo.

  3. Aquí hay un ejemplo de trabajo:

     import json answers = '[{"preview":true,"offset":0,"result":{"Country":"AU","count":"417"}}' + \ ',{"preview":true,"offset":1,"result":{"Country":"BG","count":"7"}}]' json_obj = json.loads(answers) for i in json_obj: print i['result']['Country'], i['result']['count'] 

Para la salida de resultados.

 {"preview":true,"offset":0,"result":{"Country":"AU","count":"417"}} {"preview":true,"offset":1,"result":{"Country":"BG","count":"7"}} {"preview":true,"offset":2,"result":{"Country":"CA","count":"198"}} {"preview":true,"offset":3,"result":{"Country":"CH","count":"1"}} {"preview":true,"offset":4,"result":{"Country":"CN","count":"3"}} {"preview":true,"offset":5,"result":{"Country":"CR","count":"1"}} 

En realidad hay líneas de doc (single json). Deberías leerlos línea por línea, no por todas las líneas.

Aquí está la sugerencia. Puede guardar temporalmente sus documentos JSON y luego leerlos y cargarlos.

  1. test.sh > tmp.txt
  2. léelo línea por línea

with open('tmp.txt', 'r') as f: for i in f: doc = f.readline() try: the_dict = json.loads(doc) print(the_dict['Country']) except Exception, e: print(str(e)) O si insiste en usar el subproceso, aún puede leer el archivo línea por línea. Solo recuerda que la salida que obtuviste es una lista. Deberías usar un bucle para iterar todo.

Una solución simple sería, Comencemos con su respuesta:

 answer = '''{"preview":true,"offset":0,"result":{"Country":"AU","count":"417"}} {"preview":true,"offset":1,"result":{"Country":"BG","count":"7"}} {"preview":true,"offset":2,"result":{"Country":"CA","count":"198"}} {"preview":true,"offset":3,"result":{"Country":"CH","count":"1"}} {"preview":true,"offset":4,"result":{"Country":"CN","count":"3"}} {"preview":true,"offset":5,"result":{"Country":"CR","count":"1"}} {"preview":true,"offset":6,"result":{"Country":"DE","count":"148"}} {"preview":true,"offset":7,"result":{"Country":"DK","count":"1"}} {"preview":true,"offset":8,"result":{"Country":"FI","count":"1"}} {"preview":true,"offset":9,"result":{"Country":"FR","count":"1052"}} {"preview":true,"offset":10,"result":{"Country":"GB","count":"1430"}} {"preview":true,"offset":11,"result":{"Country":"HK","count":"243"}} {"preview":false,"offset":12,"lastrow":true,"result":{"Country":"VG","count":"54"}}''' 

convertirlo en un json válido

 import json answer = json.loads('['+answer.replace('\n',',')+']') 

imprime tus resultados:

 for i in answer: print i['result']['Country'],i['result']['count'] AU 417 BG 7 CA 198 CH 1 CN 3 CR 1 DE 148 DK 1 FI 1 FR 1052 GB 1430 HK 243 VG 54 

Entonces tu código completo es:

 import subprocess import json answer = subprocess.check_output(['./test.sh']) answer = json.loads('['+answer.replace('\n',',')+']') for i in answer: print i['result']['Country'],i['result']['count'] 

Sus datos son múltiples objetos json.

Es posible que desee envolverlo entre corchetes ( { y } ) y tratarlo como un conjunto único de todos sus objetos.

 { {"preview":true,"offset":0,"result":{"Country":"AU","count":"417"}} {"preview":true,"offset":1,"result":{"Country":"BG","count":"7"}} {"preview":true,"offset":2,"result":{"Country":"CA","count":"198"}} {"preview":true,"offset":3,"result":{"Country":"CH","count":"1"}} {"preview":true,"offset":4,"result":{"Country":"CN","count":"3"}} {"preview":true,"offset":5,"result":{"Country":"CR","count":"1"}} {"preview":true,"offset":6,"result":{"Country":"DE","count":"148"}} {"preview":true,"offset":7,"result":{"Country":"DK","count":"1"}} {"preview":true,"offset":8,"result":{"Country":"FI","count":"1"}} {"preview":true,"offset":9,"result":{"Country":"FR","count":"1052"}} {"preview":true,"offset":10,"result":{"Country":"GB","count":"1430"}} {"preview":true,"offset":11,"result":{"Country":"HK","count":"243"}} {"preview":false,"offset":12,"lastrow":true,"result":{"Country":"VG","count":"54"}} }