解析 JSON 对象的最有效方法 [重复]
Posted
技术标签:
【中文标题】解析 JSON 对象的最有效方法 [重复]【英文标题】:Most effective way to parse JSON Objects [duplicate] 【发布时间】:2021-08-20 12:27:01 【问题描述】:我目前正在尝试访问 JSON 对象中的特定值,我正在使用 Try / except 语句成功地做到这一点。
由于我还在学习 Python,我想知道是否有更有效的方法来实现这一点。我经常发现,对于不同的 JSON 数据集,键/值对会移动,我必须在我的代码中手动更改索引值,从 [0] [1] [2] 或 [3]
JSON 数据:
"notifications": [
"timestamp": "1619847600000000000",
"path_elements": [
"Devices",
"NME39488200",
"versioned-data",
"interfaces",
"data",
"Ethernet1",
"aggregate",
"rates",
"1m"
],
"updates":
"alignmentErrors":
"key": "alignmentErrors",
"value":
"avg":
"float": 0
,
"max":
"float": 0
,
"min":
"float": 0
,
"stddev":
"float": 0
,
"weight":
"float": 1
,
"fcsErrors":
"key": "fcsErrors",
"value":
"avg":
"float": 0
,
"max":
"float": 0
,
"min":
"float": 0
,
"stddev":
"float": 0
,
"weight":
"float": 1
,
"frameTooLongs":
"key": "frameTooLongs",
"value":
"avg":
"float": 0
,
"max":
"float": 0
,
"min":
"float": 0
,
"stddev":
"float": 0
,
"weight":
"float": 1
,
"frameTooShorts":
"key": "frameTooShorts",
"value":
"avg":
"float": 0
,
"max":
"float": 0
,
"min":
"float": 0
,
"stddev":
"float": 0
,
"weight":
"float": 1
,
"inErrors":
"key": "inErrors",
"value":
"avg":
"float": 0
,
"max":
"float": 0
,
"min":
"float": 0
,
"stddev":
"float": 0
,
"weight":
"float": 1
,
"outDiscards":
"key": "outDiscards",
"value":
"avg":
"float": 0
,
"max":
"float": 0
,
"min":
"float": 0
,
"stddev":
"float": 0
,
"weight":
"float": 1
,
"outErrors":
"key": "outErrors",
"value":
"avg":
"float": 0
,
"max":
"float": 0
,
"min":
"float": 0
,
"stddev":
"float": 0
,
"weight":
"float": 1
,
"symbolErrors":
"key": "symbolErrors",
"value":
"avg":
"float": 0
,
"max":
"float": 0
,
"min":
"float": 0
,
"stddev":
"float": 0
,
"weight":
"float": 1
,
"timestamp": "1622629140000000000",
"path_elements": [
"Devices",
"NME39488200",
"versioned-data",
"interfaces",
"data",
"Ethernet11",
"aggregate",
"rates",
"1m"
],
"updates":
"inMulticastPkts":
"key": "inMulticastPkts",
"value":
"avg":
"float": 0.03333333333333334
,
"max":
"float": 0.1
,
"min":
"float": 0
,
"stddev":
"float": 0.047140452079103175
,
"weight":
"float": 1
,
"inOctets":
"key": "inOctets",
"value":
"avg":
"float": 269348.4166666667
,
"max":
"float": 341898.5
,
"min":
"float": 223613.3
,
"stddev":
"float": 45132.897905054306
,
"weight":
"float": 0.9999999999999999
,
"inUcastPkts":
"key": "inUcastPkts",
"value":
"avg":
"float": 300.3333333333333
,
"max":
"float": 364
,
"min":
"float": 258.8
,
"stddev":
"float": 44.179847089921985
,
"weight":
"float": 0.9999999999999999
,
"outMulticastPkts":
"key": "outMulticastPkts",
"value":
"avg":
"float": 0.03333333333333334
,
"max":
"float": 0.1
,
"min":
"float": 0
,
"stddev":
"float": 0.047140452079103175
,
"weight":
"float": 0.9999999999999999
,
"outOctets":
"key": "outOctets",
"value":
"avg":
"float": 28700.35
,
"max":
"float": 42799.9
,
"min":
"float": 17571.2
,
"stddev":
"float": 9737.234046475074
,
"weight":
"float": 0.9999999999999999
,
"outUcastPkts":
"key": "outUcastPkts",
"value":
"avg":
"float": 196.13333333333333
,
"max":
"float": 237
,
"min":
"float": 164.4
,
"stddev":
"float": 28.93957305989306
,
"weight":
"float": 0.9999999999999999
,
"timestamp": "1620649440000000000",
"path_elements": [
"Devices",
"NME39488200",
"versioned-data",
"interfaces",
"data",
"Ethernet11",
"aggregate",
"rates",
"1m"
],
"updates":
"inDiscards":
"key": "inDiscards",
"value":
"avg":
"float": 0
,
"max":
"float": 0
,
"min":
"float": 0
,
"stddev":
"float": 0
,
"weight":
"float": 1
,
"timestamp": "1621745580000000000",
"path_elements": [
"Devices",
"JPE13031399",
"versioned-data",
"interfaces",
"data",
"Ethernet11",
"aggregate",
"rates",
"1m"
],
"updates":
"inBroadcastPkts":
"key": "inBroadcastPkts",
"value":
"avg":
"float": 0
,
"max":
"float": 0
,
"min":
"float": 0
,
"stddev":
"float": 0
,
"weight":
"float": 1
,
"outBroadcastPkts":
"key": "outBroadcastPkts",
"value":
"avg":
"float": 0
,
"max":
"float": 0
,
"min":
"float": 0
,
"stddev":
"float": 0
,
"weight":
"float": 1
]
我从多个 URL 获取 JSON 数据。我用来从 Key: 'InDiscards' 或 'OutDiscards' 中提取值 'Avg' 的代码如下:
for url in URLs:
JSONdata = requests.get(url, cookies=cookies, verify=False).json()
JSONkey = JSONdata["notifications"]
name = JSONkey[0]["path_elements"][1]
interface = JSONkey[0]["path_elements"][5]
try:
outDiscards = JSONkey[0]["updates"]["outDiscards"]["value"]["avg"]["float"]
except KeyError:
outDiscards = JSONkey[2]["updates"]["outDiscards"]["value"]["avg"]["float"]
try:
inDiscards = JSONkey[0]["updates"]["inDiscards"]["value"]["avg"]["float"]
except KeyError:
inDiscards = JSONkey[2]["updates"]["inDiscards"]["value"]["avg"]["float"]
我的理解是我们检查 index [0] 的 OutDiscards (或 InDiscards) 的平均值,如果我们找不到值,我们然后检查 index [2] ,但是肯定有更好的方法鉴于有时索引可能是 1/3/4/5 等,因此实现这一点......
【问题讨论】:
这能回答你的问题吗? How to convert JSON data into a Python object 【参考方案1】:我建议使用 for 循环进行搜索。
首先初始化您的变量,我使用None
,以便稍后确定我的搜索例程是否找到了一些东西
outDiscards = None
inDiscards = None
然后遍历通知列表中的所有元素
for notification in JSONdata["notifications"]:
仅在尚未找到该值时尝试访问该值
if outDiscards is None:
尝试访问该值并忽略 KeyError
try:
outDiscards = notification["updates"]["outDiscards"]["value"]["avg"]["float"]
except KeyError:
pass
if inDiscards is None:
try:
inDiscards = notification["updates"]["inDiscards"]["value"]["avg"]["float"]
except KeyError:
pass
在搜索例程之后应该有 outDiscards 和 inDiscards 中的值,您可以使用 if outDiscards is not None
进行测试
print(outDiscards)
print(inDiscards)
【讨论】:
这很好用,但是我不明白为什么,我自己也无法找到解决方案,能否解释一下为什么会这样? 你需要什么解释?我应该澄清 JSONdata["notifications"] 中的通知吗? 关于=none,然后在那个变量上循环 我编辑了我的答案以澄清以上是关于解析 JSON 对象的最有效方法 [重复]的主要内容,如果未能解决你的问题,请参考以下文章