Python以更好的方式解析JSON数据



我有一些JSON数据需要解析。但不能完全正确,代码看起来不太好。

我的第一个问题是,这可以用一种比使用嵌套for循环更好的方式来编写吗?

的第二个问题。基于JSON结构的设置,我无法获得可靠的输出。我希望得到低于输出的值。但是因为我。0和inet。6是在同一水平,不能两者都得到。有没有简单的方法得到这个?

('192.168.0.1', 'Established', 'test-x1', '11996', '463')
('192.168.1.2', 'down', 'test-x2', '31996', '363')
#!/usr/bin/python3
import json
json_input = """
{
"bgp-information" : [
{
"attributes" : {"xmlns" : "http://xml.juniper.net/junos/0/junos-routing"}, 
"bgp-thread-mode" : [
{
"data" : "BGP I/O"
}
], 
"thread-state" : [
{
}
], 
"group-count" : [
{
"data" : "23"
}
], 
"peer-count" : [
{
"data" : "31"
}
], 
"down-peer-count" : [
{
"data" : "2"
}
], 
"bgp-peer" : [
{
"attributes" : {"junos:style" : "terse", 
"heading" : "Peer                     AS      InPkt     OutPkt    OutQ   Flaps Last Up/Dwn State|#Active/Received/Accepted/Damped..."
}, 
"peer-address" : [
{
"data" : "192.168.0.1"
}
], 
"peer-as" : [
{
"data" : "65000"
}
], 
"input-messages" : [
{
"data" : "550950"
}
], 
"output-messages" : [
{
"data" : "41235"
}
], 
"route-queue-count" : [
{
"data" : "0"
}
], 
"flap-count" : [
{
"data" : "4"
}
], 
"elapsed-time" : [
{
"data" : "19w0d 23:55:24", 
"attributes" : {"junos:seconds" : "11577324"}
}
], 
"description" : [
{
"data" : "test-x1"
}
], 
"peer-state" : [
{
"data" : "Established", 
"attributes" : {"junos:format" : "Establ"}
}
], 
"bgp-rib" : [
{
"attributes" : {"junos:style" : "terse"}, 
"name" : [
{
"data" : "inet.0"
}
], 
"active-prefix-count" : [
{
"data" : "9292"
}
], 
"received-prefix-count" : [
{
"data" : "11929"
}
], 
"accepted-prefix-count" : [
{
"data" : "11996"
}
], 
"suppressed-prefix-count" : [
{
"data" : "0"
}
]
}, 
{
"attributes" : {"junos:style" : "terse"}, 
"name" : [
{
"data" : "inet6.0"
}
], 
"active-prefix-count" : [
{
"data" : "48"
}
], 
"received-prefix-count" : [
{
"data" : "493"
}
], 
"accepted-prefix-count" : [
{
"data" : "463"
}
], 
"suppressed-prefix-count" : [
{
"data" : "0"
}
]
}
]
},
{
"attributes" : {"junos:style" : "terse"}, 
"peer-address" : [
{
"data" : "192.168.1.2"
}
], 
"peer-as" : [
{
"data" : "65001"
}
], 
"input-messages" : [
{
"data" : "679978"
}
], 
"output-messages" : [
{
"data" : "43663"
}
], 
"route-queue-count" : [
{
"data" : "0"
}
], 
"flap-count" : [
{
"data" : "2"
}
], 
"elapsed-time" : [
{
"data" : "20w1d 20:40:58", 
"attributes" : {"junos:seconds" : "1256858"}
}
], 
"description" : [
{
"data" : "test-x2"
}
], 
"peer-state" : [
{
"data" : "down", 
"attributes" : {"junos:format" : "Establ"}
}
], 
"bgp-rib" : [
{
"attributes" : {"junos:style" : "terse"}, 
"name" : [
{
"data" : "inet.0"
}
], 
"active-prefix-count" : [
{
"data" : "9953"
}
], 
"received-prefix-count" : [
{
"data" : "31996"
}
], 
"accepted-prefix-count" : [
{
"data" : "31996"
}
], 
"suppressed-prefix-count" : [
{
"data" : "0"
}
]
}, 
{
"attributes" : {"junos:style" : "terse"}, 
"name" : [
{
"data" : "inet6.0"
}
], 
"active-prefix-count" : [
{
"data" : "98"
}
], 
"received-prefix-count" : [
{
"data" : "463"
}
], 
"accepted-prefix-count" : [
{
"data" : "363"
}
], 
"suppressed-prefix-count" : [
{
"data" : "0"
}
]
}
]
}
]
}
]
}
"""
json_out = json.loads(json_input)
for value1 in json_out['bgp-information']:
for value2 in value1['bgp-peer']:
for value in value2['peer-address']:
peer = (value['data'])
for value in value2['peer-state']:
state = (value['data'])
for value in value2['description']:
desc = (value['data'])        
for value3 in value2['bgp-rib']: # Below part is what i need help with. Assign first hit to variable inet0_accepted_prefix_count and second to inet6_accepted_prefix_count                   
for value in value3['accepted-prefix-count']:     
inet0_accepted_prefix_count = (value['data'])
for value in value3['accepted-prefix-count']: 
inet6_accepted_prefix_count = (value['data'])       
print(inet0_accepted_prefix_count,inet6_accepted_prefix_count)
combined = (peer,state,desc,inet0_accepted_prefix_count,inet6_accepted_prefix_count) #inet0_accepted_prefix_count is missing
print(combined)

您需要收集名称:"inet.0""inet6.0"作为单独的dict中的条目,以便能够收集相关的"accepted-prefix-count"值:

# json string elided
json_out = json.loads(json_input)
for value1 in json_out['bgp-information']:
for value2 in value1['bgp-peer']:
for value in value2['peer-address']:
peer = (value['data'])
for value in value2['peer-state']:
state = (value['data'])
for value in value2['description']:
desc = (value['data'])
d = {}
for value3 in value2['bgp-rib']:                   
for value in value3['name']:     
name = value['data']
for value in value3['accepted-prefix-count']: 
accepted_prefix_count = value['data']    
d[name] = accepted_prefix_count
combined = (peer, state, desc, d['inet.0'], d['inet6.0']) 
print(combined)

按要求输出

这段代码应该可以满足您的需要。你可以通过去掉"data"来改进/缩短json数据的结构。命名空间,但前提是您知道不会向目录

追加任何内容。考试。- "description":[{"data"; "test-x2"}]变成- "description"test-x2">

,但这段代码应该与您当前的json:

json_out = json.loads(json_input)
for value in json_out["bgp-information"][0]["bgp-peer"]:
peer = value["peer-address"][0]["data"]
state = value["peer-state"][0]["data"]
desc = value["description"][0]["data"]
inet0_accepted_prefix_count = value["bgp-rib"][0]["accepted-prefix-count"][0]["data"]
inet6_accepted_prefix_count = value["bgp-rib"][1]["accepted-prefix-count"][0]["data"]
combined = (peer,state,desc,inet0_accepted_prefix_count,inet6_accepted_prefix_count)
print(combined)

与其他供应商相比,Juniper JSON输出的格式不是很简单,所以我需要引入一些例外情况。如果有人需要解析Junos BGP输出,这里有一个基于@MarcusDevs答案的示例:

json_out = json.loads(json_input)   
for value in json_out["bgp-information"][0]["bgp-peer"]:
peer = value["peer-address"][0]["data"]
state = value["peer-state"][0]["data"]
try:
desc = value["description"][0]["data"]
except:
desc = "X"
try:
for value1 in value["bgp-rib"]:
try:
name = value1["name"][0]["data"]
except:
name = "X" 
try:
accepted_prefix_count = value1["accepted-prefix-count"][0]["data"]
except:
accepted_prefix_count = "X"
combined = (peer,state,accepted_prefix_count,name,desc)
print(combined)
except:
name = "X" 
accepted_prefix_count = "X"
combined = (peer,state,accepted_prefix_count,name,desc)
print(combined)

最新更新