如何使用 ijson 从 json 文件中提取一组相应的数据?

How can i use ijson to extract a set of corresponding data from json file?

我有一个 json 文件,就像这样:

    {
  "CVE_data_type" : "CVE",
  "CVE_Items" : [ {
    "cve" : {

      "CVE_data_meta" : {
        "ID" : "CVE-2020-0001",
        "ASSIGNER" : "security@android.com"
      },
      ...
      
    "configurations" : {
      "CVE_data_version" : "4.0",
      "nodes" : [ {
        "operator" : "OR",
        "children" : [ ],
        "cpe_match" : [ {
          "vulnerable" : true,
          "cpe23Uri" : "cpe:2.3:o:google:android:8.0:*:*:*:*:*:*:*",
          "cpe_name" : [ ]
        }, {
          "vulnerable" : true,
          "cpe23Uri" : "cpe:2.3:o:google:android:8.1:*:*:*:*:*:*:*",
          "cpe_name" : [ ]
        }]
      } ]
    },
   ...
    "publishedDate" : "2020-01-08T19:15Z",
    "lastModifiedDate" : "2020-01-14T21:52Z"
  }]
}

而且我想提取CVE-ID和相应的CPE,所以我可以通过CPE涂上CVE-ID,这是我的代码

import ijson
import datetime


def parse_json(filename):
    with open(filename, 'rb') as input_file:
        CVEID = ijson.items(input_file, 'CVE_Items.item.cve.CVE_data_meta.ID', )
        for id in CVEID:
            print("CVE id: %s" % id)
        # for prefix, event, value in parser:
        #     print('prefix={}, event={}, value={}'.format(prefix, event, value))

    with open(filename, 'rb') as input_file:
        cpes = ijson.items(input_file, 'CVE_Items.item.configurations.nodes.item.cpe_match.item', )
        for cpe in cpes:
            print("cpe: %s" % cpe['cpe23Uri'])


def main():
    
    parse_json("cve.json")
    end = datetime.datetime.now()
    

if __name__ == '__main__':
    main()

结果:

CVE id: CVE-2020-0633
CVE id: CVE-2020-0631
cpe: cpe:2.3:o:google:android:8.0:*:*:*:*:*:*:*
cpe: cpe:2.3:o:google:android:10.0:*:*:*:*:*:*:*
cpe: cpe:2.3:o:microsoft:windows_10:1607:*:*:*:*:*:*:*
cpe: cpe:2.3:o:microsoft:windows_server_2016:-:*:*:*:*:*:*:*

但是上面这个只是提取数据并没有对应关系。

有人能帮忙吗?如果能提供一点帮助,我们将不胜感激。

我认为如果您需要跟踪 CVE ID 及其相应的 CPE,您将需要遍历整个 cve 项并提取所需的数据位(因此您只需执行一个通过文件)。在内存方面不如您的原始迭代高效,但如果 CVE_Items 中的每个项目都不是太大,那么这不是问题:

with open(filename, 'rb') as input_file:
    for cves in ijson.items(input_file, 'CVE_Items.item')
        cve_id = cve['cve']['CVE_data_meta']['ID']
        cpes = [match
                for node in cve['configurations']['nodes']
                for match in node['cpe_match']]

如果您知道 nodes 中始终只有一个 cpe_match 元素,那么您可以将最后一个列表理解替换为 cve['configurations']['nodes'][0]['cpe_match']