Python/API 请求 - 从具有动态输出的 API 请求中提取数据



我是第一次使用 API 请求,我想知道是否可以执行以下操作:

我有一个函数可以接收如下所示的 API 响应:

{
"DATA_Items": [{
"DATA": {
"DATA_data_meta": {
"ASSIGNER": "info@gmail.com",
"ID": "DATA-2021-43062"
},
"data_format": "IRE",
"data_type": "DATA",
"data_version": "4.0",
"description": {
"description_data": [{
"lang": "en",
"value": "during web page generation."
}]
},
"problemtype": {
"problemtype_data": [{
"description": [{
"lang": "en",
"value": "CWE-79"
}]
}]
},
"references": {
"reference_data": [{
"name": "https://blablabla/data",
"refsource": "CONFIRM",
"tags": ["Advisory"],
"url": "https://blablabl/data"
},
{
"name": "http://blablabla.com/files/166055/mail-7.0.1-Cross-Site-Scripting.html",
"refsource": "MISC",
"tags": ["Exploit",
"Advisory",
"Entry"
],
"url": "http://package.com/files/166055/mail-7.0.1-Cross-Site-Scripting.html"
}
]
}
},
"configurations": {
"DATA_data_version": "4.0",
"nodes": [{
"ID_match": [{
"ID23Uri": "ID:2.3:a:info:mail:*:*:*:*:*:*:*:*",
"ID_name": [],
"versionEndExcluding": "2.0.2",
"versionStartIncluding": "3.0.0",
"vulnerable": true
},
{
"ID23Uri": "ID:2.3:a:info:mail:*:*:*:*:*:*:*:*",
"ID_name": [],
"versionEndExcluding": "6.46",
"versionStartIncluding": "9.7.0",
"vulnerable": true
},
{
"ID23Uri": "ID:2.3:a:info:mail:*:*:*:*:*:*:*:*",
"ID_name": [],
"versionEndExcluding": "6.2.8",
"versionStartIncluding": "2.2.0",
"vulnerable": true
}
],
"children": [],
"operator": "OR"
}]
},
"impact": {
"baseMetricV2": {
"acInsufInfo": false,
"datasV2": {
"Impact": "NONE",
"accessComplexity": "MEDIUM",
"accessVector": "NETWORK",
"authentication": "NONE",
"availabilityImpact": "NONE",
"baseScore": 4.3,
"integrityImpact": "PARTIAL",
"vectorString": "AV:N/AC:M/Au:N/C:N/I:P/A:N",
"version": "2.0"
},
"exploitabilityScore": 8.6,
"impactScore": 2.9,
"obtainAllPrivilege": false,
"obtainOtherPrivilege": false,
"obtainUserPrivilege": false,
"severity": "MEDIUM",
"userInteractionRequired": true
},
"baseMetricV3": {
"Score": 2.8,
"impactScore": 1.7,
"sV3": {
"Complexity": "LOW",
"Vector": "NETWORK",
"availabilityImpact": "NONE",
"baseScore": 6.1,
"baseSeverity": "MEDIUM",
"confidentialityImpact": "LOW",
"integrityImpact": "LOW",
"privilegesRequired": "NONE",
"scope": "CHANGED",
"userInteraction": "REQUIRED",
"vectorString": "BASE",
"version": "3.1"
}
}
},
"lastModifiedDate": "2012-03-04T16:33Z",
"publishedDate": "2012-05-02T11:15Z"
}]
}

我感兴趣的部分是:

{"ID_match": [{"vulnerable": true 

ID_match之后的vulnerable总是相同的。

但是,ID_match可以在 API 调用的多个位置,我不确定所有不同的可能性。我确实有一些代码循环访问一些ID_matches,如下所示:

date = datetime.datetime.now() + datetime.timedelta(days=-1)
response = requests.get('https://somewebsite?dataMatchString={}&modStartDate={}-{:02d}-{:02d}T00:00:00:000%20CEST&modEndDate={}-{:02d}-{:02d}T00:00:00:000%20CEST'.format(
application.id, date.year, date.month, date.day - 1, date.year, date.month, date.day + 2)).json()
for check in response['result']['DATA_Items'][0]['configurations']['nodes'][0]['children'][0]['ID_match']:
print(check)
for check2 in response['result']['DATA_Items'][0]['configurations']['nodes'][0]['children'][1]['ID_match']:
print(check2)
for check3 in response['result']['DATA_Items'][0]['configurations']['nodes'][0]['ID_match']:
print(check3)

当我这样做时,我确实看到对于某些 API 响应,我确实打印了我想要的部分,但它也错过了一些。

我想知道是否可以搜索ID_match所在的路径,然后使用它来获取vulnerable的值

您可以使用递归函数遍历整个对象图,查看所有嵌套字典和所有列表项,并返回具有'vulnerable': True条目的字典。

def find_vulnerable_nodes(node):
if isinstance(node, list):
for item in node:
yield from find_vulnerable_nodes(item)
elif isinstance(node, dict):
if node.get('vulnerable') == True:
yield node
else:
for item in node.values():
yield from find_vulnerable_nodes(item)

这样,输入数据的结构和嵌套深度就无关紧要了。

用法:

data = requests.get('...').json()
for n in find_vulnerable_nodes(data):
print(n)

vulnerable_nodes = list(find_vulnerable_nodes(data))

示例数据的结果:

{'ID23Uri': 'ID:2.3:a:info:mail:*:*:*:*:*:*:*:*', 'ID_name': [], 'versionEndExcluding': '2.0.2', 'versionStartIncluding': '3.0.0', 'vulnerable': True}
{'ID23Uri': 'ID:2.3:a:info:mail:*:*:*:*:*:*:*:*', 'ID_name': [], 'versionEndExcluding': '6.46', 'versionStartIncluding': '9.7.0', 'vulnerable': True}
{'ID23Uri': 'ID:2.3:a:info:mail:*:*:*:*:*:*:*:*', 'ID_name': [], 'versionEndExcluding': '6.2.8', 'versionStartIncluding': '2.2.0', 'vulnerable': True}

最新更新