提问人:Dinerz 提问时间:3/20/2023 更新时间:3/21/2023 访问量:117
从 JSON 输出中切片和提取特定值
Slice and extract specific values from JSON output
问:
我正在查询 REST API,我需要从下面的适配器输出中选择 2 个字段,查询将包含多个事件编号。
我基本上需要从下面的输出中列出事件编号和描述。
用于获取数据的代码:
headers = {'content-type': 'application/json', 'Authentication-Token': authToken}
response = requests.post('http://dev.startschools.local:2031/baocdp/rest/process/:ITSM_Interface:IncidentManagement:QueryIncident/execute', headers=headers, data=json.dumps(get_query_inc_json()))
print(response.text)
response.text printed 输出:
[{"name":"Adapter_Output","value":"<query-action-result><entries><metadata><entry-count>2</entry-count></metadata><entry id=\"INC000003197686|INC000003197686\"><field name=\"Incident Number\">INC000021</field><field name=\"Description\">Student needs a new card issued</field></entry><entry id=\"INC000003198967|INC000003198967\"><field name=\"Incident Number\">INC000035</field><field name=\"Description\">Students cannot access the text book portal</field></entry></entries></query-action-result>"}]
我需要获取事件编号和描述的列表,以便可以遍历它们:
事件编号列表 1:
["INC000021", "INC000035"]
描述列表 2:
["Student needs a new card issued", "Students cannot access the text book portal"]
我正在尝试使用切片将所有事件编号放入一个列表中,但由于输出不断变化,切片不起作用。
有谁知道除了切片之外更有效的方法来从此输出中提取我需要的信息?
答:
1赞
jjislam
3/20/2023
#1
试试这个。
data = response.text
value = data[0]["value"]
i_nums = [x.split("</field")[0] for x in value.split('<field name=\"Incident Number\">')[1:]]
desc = [x.split("</field")[0] for x in value.split('<field name=\"Description\">')[1:]]
print(i_nums)
print(desc)
评论
1赞
chepner
3/20/2023
data
是一个字符串,而不是字典列表。
1赞
Dinerz
3/20/2023
这太棒了,chepner 是正确的,需要使用 json.load,然后您的解决方案运行完美。谢谢@jjislam
1赞
Rodrigo Rodrigues
3/20/2023
#2
尽管 @jjislam 的回答为您的示例提供了正确的答案,但我建议您使用适当的 xml 解析器来浏览您的结果,因为这是首先拥有结构化数据的实际意图!
这是有关如何使用内置包的代码片段。一旦你了解了这里发生的事情,你就可以很容易地将其转换为带有理解的单行。xml.etree
import xml.etree.ElementTree
responseText = [{"name":"Adapter_Output","value":"<query-action-result><entries><metadata><entry-count>2</entry-count></metadata><entry id=\"INC000003197686|INC000003197686\"><field name=\"Incident Number\">INC000021</field><field name=\"Description\">Student needs a new card issued</field></entry><entry id=\"INC000003198967|INC000003198967\"><field name=\"Incident Number\">INC000035</field><field name=\"Description\">Students cannot access the text book portal</field></entry></entries></query-action-result>"}]
# the root will be the topmost element, in this case the one with tag "query-action-result"
root = xml.etree.ElementTree.fromstring(responseText[0]["value"])
incidents, descriptions = [], []
# iterate recursively over all elements with tag "entry" that are children of the root element
for entry in root.iter('entry'):
# within each entry, find the first element with tag "field" and attribute "name=Incident Number", and capture its content
incident = entry.find("field[@name='Incident Number']").text
# same, but with attribute "name=Description"
description = entry.find("field[@name='Description']").text
print(incident, description)
incidents.append(incident)
descriptions.append(description)
print(incidents)
print(descriptions)
评论
0赞
Dinerz
3/20/2023
谢谢也会尝试这个解决方案。只需要多了解一下XML.etree。
0赞
Rodrigo Rodrigues
3/21/2023
我添加了一些注释来帮助您理解代码
评论
response.text
是一个字符串;您需要使用将字符串解码为 Python ,或用于获取响应的预解码版本。json.loads(response.text)
dict
response.json()