【问题标题】:TypeError: string indices must be integers, not str with JSON parsingTypeError:字符串索引必须是整数,而不是带有 JSON 解析的 str
【发布时间】:2018-08-02 22:20:22
【问题描述】:

我在尝试解析 JSON 文件时遇到上述错误。

代码:

import json

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

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

追溯:

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"
                 }
             }
          ]
       }
    }
}

由于某种原因,host 似乎是一个字符串,我不确定如何克服这个错误。

【问题讨论】:

  • 您导入了json,但不要使用它。打开文件和json.load(file)

标签: python json


【解决方案1】:

这不是打开 json 文件的好方法。 open('output.json').read() 将您的文件作为字符串返回。 更好的方法是:

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'])

【讨论】:

    【解决方案2】:

    您有几个问题,一些在您的代码中,一些在您的 JSON 中。

    首先,JSON --- 在最后一个列表条目之后有一个额外的逗号:

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

    您的代码有两个问题。 首先是您永远不会将文件的内容转换为 JSON --- 它仍然是一个字符串:

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

    你想要类似的东西 roganjosh already described:

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

    您的后续问题是 JSON 的结构与您的代码不匹配。 'IMAGE_ID' 不是 (未命名) 存储在 'HOST' 列表中的字典 --- 它是 'EC2_INFO' 字典的键,包含在那个无名字典中。 这个:

    print(host['IMAGE_ID'])
    

    应该是这样的:

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

    输出是一个字符串:

    ami-xxxxxx
    

    【讨论】:

    • 我现在明白了。这是正确的,并且在我测试后也有效。
    【解决方案3】:

    导入json 是不够的。 data = open('output.json').read() 只是将其视为任何其他文件。

    TypeError: string indices must be integers, not str 没有抱怨'HOST' 键; data['ASSET_DATA_REPORT'] 本身也无效,因为整个东西都是一个字符串。

    试试:

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

    正如@Milton Arango G 所指出的,您发布的 JSON 中有一个错误。变化:

    "IF - Database - MySQL",
    

    到:

    "IF - Database - MySQL"
    

    之后,您可以通过以下方式获取'IMAGE_ID' 字段:

    print(data['ASSET_DATA_REPORT']['HOST_LIST']['HOST'][0]['EC2_INFO']['IMAGE_ID'])
    

    【讨论】:

    • 返回以下错误:Traceback (most recent call last): File "json_format.py", line 16, in &lt;module&gt; print(host['IMAGE_ID']) KeyError: 'IMAGE_ID'
    • 另外,您的 json 文件中存在一个错误,导致无法对其进行解码,您可以使用 JsonFormatter 进行检查。只需删除"IF - Database - MySQL", 中的逗号,roganjosh 答案就可以工作,或者您可以使用那里的 for 循环对其进行迭代。
    • @NickD。这无关紧要,您现在拥有一个可以实际访问的嵌套字典和列表结构。 host['IMAGE_ID'] 不会让您访问 'IMAGE_ID' 密钥,但我需要一点时间才能获得该密钥。等等。
    • @MiltonArangoG 好地方,谢谢。将答案归功于您,
    • @NickD。针对 JSON 修复进行了编辑(我认为这是您的复制/粘贴错误,因为否则无法读取文件)并向您展示如何访问您请求的值。
    猜你喜欢
    • 2013-12-16
    • 1970-01-01
    • 2021-08-28
    • 1970-01-01
    • 2019-03-07
    • 2013-09-06
    • 2020-06-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多