Recibo el error anterior al intentar analizar un archivo JSON.

Código:

import json

data = open('output.json').read()

for host in data['ASSET_DATA_REPORT']['HOST_LIST']['HOST']:
        print(host['IMAGE_ID'])

Rastreo:

Traceback (most recent call last):
  File "json_format.py", line 11, in <module>
    for host in data['ASSET_DATA_REPORT']['HOST_LIST']['HOST']:
TypeError: string indices must be integers, not str

JSON:

{
"ASSET_DATA_REPORT": {
  "HOST_LIST": {
            "HOST": [
                {
                    "IP": {
                        "network_id": "0"
                    }, 
                    "TRACKING_METHOD": "EC2", 
                    "ASSET_TAGS": {
                        "ASSET_TAG": [
                            "EC2 Running", 
                            "IF - Database - MySQL", 
                        ]
                    }, 
                    "DNS": "i-xxxxxxx", 
                    "EC2_INSTANCE_ID": "i-xxxxxx", 
                    "EC2_INFO": {
                        "PUBLIC_DNS_NAME": "ec2-xxxxxxxx.amazonaws.com", 
                        "IMAGE_ID": "ami-xxxxxx", 
                        "VPC_ID": "vpc-xxxxxx", 
                        "INSTANCE_STATE": "RUNNING", 
                        "PRIVATE_DNS_NAME": "ip-xxxx.ec2.internal", 
                        "INSTANCE_TYPE": "m3.xlarge"
                 }
             }
          ]
       }
    }
}

Parece que host es una cadena por alguna razón y no estoy seguro de cómo superar este error.

1
user9300944 23 feb. 2018 a las 01:08

3 respuestas

La mejor respuesta

Tiene un par de problemas, algunos en su código, otros en su JSON.

Primero, el JSON --- tienes una coma extra después de la última entrada de la lista:

"ASSET_TAG": [
    "EC2 Running",
    "IF - Database - MySQL",
]

Tu código tiene dos problemas. Primero es que nunca convierte los contenidos del archivo a JSON --- sigue siendo una cadena:

data = open('output.json').read()

Quieres algo como roganjosh ya descrito:

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

Su problema de seguimiento es que la estructura de JSON no coincide con su código. 'IMAGE_ID' no es una clave en el (sin nombre) diccionario almacenado en la lista 'HOST' --- es una clave del diccionario 'EC2_INFO', que está contenido dentro de ese diccionario sin nombre. Esta:

print(host['IMAGE_ID'])

Debería ser algo como:

print(host['EC2_INFO']['IMAGE_ID'])

El resultado es una cadena:

ami-xxxxxx
0
Kevin J. Chase 22 feb. 2018 a las 22:38

Esa no es una buena manera de abrir un archivo json. open('output.json').read() devuelve tu archivo como cadena. Una mejor manera es:

import json

with open('output.json', 'r') as my_file:
    data = json.load(my_file)

for host in data['ASSET_DATA_REPORT']['HOST_LIST']['HOST']:
        print(host['IMAGE_ID'])
0
Matthew Ciaramitaro 23 feb. 2018 a las 01:44

Importar json no es suficiente. data = open('output.json').read() simplemente lo trata como cualquier otro archivo.

TypeError: string indices must be integers, not str no se queja de la tecla 'HOST'; data['ASSET_DATA_REPORT'] por sí solo tampoco será válido porque todo es una cadena.

Tratar:

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

Como señaló @Milton Arango G, hay un error en el JSON que publicaste. Cambio:

"IF - Database - MySQL",

Para:

"IF - Database - MySQL"

Después de eso, puede obtener el campo 'IMAGE_ID' con:

print(data['ASSET_DATA_REPORT']['HOST_LIST']['HOST'][0]['EC2_INFO']['IMAGE_ID'])
3
roganjosh 22 feb. 2018 a las 22:38