【问题标题】:Receiving "KeyError" after decoding json result from url从 url 解码 json 结果后接收“KeyError”
【发布时间】:2014-12-06 00:18:30
【问题描述】:

我是 Python 新手。我正在尝试从 url 解析 json 结果。最初,我使用的是以下内容:

response = urllib.request.urlopen(url)
json_obj = json.load(response)

这给出了“JSON对象应该是'str'而不是'bytes'”这样的错误,所以在stackoverflow上搜索后,我将响应解码如下:

f = urllib.request.urlopen(url)
charset = f.info().get_param('charset', 'utf8')
data = f.read()
decoded = json.loads(data.decode(charset))

如果我打印“decoded”如下:

{'Links': {'SummaryData': 'https://localhost/piwebapi/streams/P0_7qHaW4UHU-RlCaz8tpasAAQAAAAU0hJTExNQU42NDIwXFNJTlVTT0lE/summary', 'Value': 'https://localhost/piwebapi/streams/P0_7qHaW4UHU-RlCaz8tpasAAQAAAAU0hJTExNQU42NDIwXFNJTlVTT0lE/value', 'InterpolatedData': 'https://localhost/piwebapi/streams/P0_7qHaW4UHU-RlCaz8tpasAAQAAAAU0hJTExNQU42NDIwXFNJTlVTT0lE/interpolated', 'Self': 'https://localhost/piwebapi/points/P0_7qHaW4UHU-RlCaz8tpasAAQAAAAU0hJTExNQU42NDIwXFNJTlVTT0lE', 'PlotData': 'https://localhost/piwebapi/streams/P0_7qHaW4UHU-RlCaz8tpasAAQAAAAU0hJTExNQU42NDIwXFNJTlVTT0lE/plot', 'DataServer': 'https://localhost/piwebapi/dataservers/s0_7qHaW4UHU-RlCaz8tpasAU0hJTExNQU42NDIw', 'RecordedData': 'https://localhost/piwebapi/streams/P0_7qHaW4UHU-RlCaz8tpasAAQAAAAU0hJTExNQU42NDIwXFNJTlVTT0lE/recorded'}, 'Id': 1, 'Name': 'SINUSOID', 'WebId': 'P0_7qHaW4UHU-RlCaz8tpasAAQAAAAU0hJTExNQU42NDIwXFNJTlVTT0lE'}

现在,每当我尝试提取特定值时,都会收到“KeyError”。例如:

print(decoded[0])

返回以下内容:

Traceback (most recent call last):
  File "C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\Extensio
ns\Microsoft\Python Tools for Visual Studio\2.1\visualstudio_py_util.py", line 1
06, in exec_file
    exec_code(code, file, global_variables)
  File "C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\Extensio
ns\Microsoft\Python Tools for Visual Studio\2.1\visualstudio_py_util.py", line 8
2, in exec_code
    exec(code_obj, global_variables)
  File "C:\Users\shillman\Documents\Visual Studio 2010\Projects\PythonApplicatio
n1\PythonApplication1\PythonApplication1.py", line 26, in <module>
    print(decoded[0])
KeyError: 0

“解码”的格式是什么?有没有办法在它实际上是一本字典的情况下做到这一点?有没有办法将其转换为字典?非常感谢任何帮助/建议!谢谢。

【问题讨论】:

    标签: python json python-3.x decode urlopen


    【解决方案1】:

    json.loads() 将 json 解码为 python 对象。 [1]

    您的decoded 已经是一个python 字典,但它没有0 的键。

    您可以使用decoded['Links']访问链接

    [1]https://docs.python.org/2/library/json.html#json.loads

    【讨论】:

    • 如果我写 print(decoded['WebID']) 我仍然得到 KeyError: 'WebID'。我做错了什么?
    • 啊,区分大小写。我得到了它。谢谢!
    【解决方案2】:

    “解码”的格式是什么?有没有办法在它实际上是一本字典的情况下做到这一点?有没有办法把它转换成字典?

    根据您打印的内容,decoded 字典,而这正是问题所在。

    这个字典的键是'Links''Name''Id''WebId'。但是decoded[0] 正在寻找带有键0 的值。没有这样的密钥,所以你会得到一个错误。

    听起来您真正想要的是一种获取第一个值的方法,将字典视为列表或其他序列。您可以将字典的键、值或项视为序列,但不能直接处理,因为:

    • 这些事情的顺序是完全任意的。
    • 字典没有理由不能将01 作为键而不是'Links''Name'
    • 因此,Python 不会让您仅使用普通的 [] 运算符来完成。

    如果你想获得字典中的第一个值——同时记住顺序是任意的,并且“第一个”可能并不意味着你想要的——你可以这样做:

    list(decoded.values())[0]
    

    ... 或者,不那么浪费,将其视为可迭代的,而不是尝试将其制成序列:

    next(iter(decoded.values())
    

    如果你还在使用 Python 2.x,values() 实际上会返回一个列表,所以这两个都是浪费和不必要的;你想改用next(decoded.itervalues())

    【讨论】:

    • 感谢您的回复。当我使用其中一个实际键时,例如: print(decoded['WebID'] 我仍然得到 "KeyError 'WebID'" 这不是引用该键的方式吗?
    • 啊,区分大小写。我不知道。现在工作。谢谢!
    • @JOEMan90:编写一个不区分大小写的 dict 子类并挂钩 json 模块以返回那些而不是正常的 dict 值并不是那么难,如果你真的想要的话。但 JSON 本身本质上是区分大小写的,因此这可能会根据您的输入数据而变得相当混乱,并且可能不是一个好主意。
    猜你喜欢
    • 2021-08-02
    • 1970-01-01
    • 1970-01-01
    • 2011-11-26
    • 2012-06-09
    • 2015-10-16
    • 2021-11-09
    • 1970-01-01
    • 2022-01-21
    相关资源
    最近更新 更多