【问题标题】:Parsing nested JSON and writing it to CSV (Revisited)解析嵌套 JSON 并将其写入 CSV(重新访问)
【发布时间】:2017-08-17 16:48:22
【问题描述】:

刚接触 Python,在下面的帖子中给出了答案:

Parsing nested JSON and writing it to CSV

如何定义输入文件以使此代码正常工作?我知道我必须将“输出文件”定义为我要写入的路径/文件名,但我只是不知道输入文件应该去哪里?

编辑:为了清楚起见,我有一个 JSON 文件作为输入,并希望将其转换为 CSV 文件作为输出。我只想知道如何编写将采用示例的代码(从上面)并让它指定一个特定的 JSON 文件作为输入。同样为清楚起见,JSON 文件的名称将保持不变,但内容会每天更改,所以我只需要知道将 open() 放在哪里 以及如何在脚本中调用它。

EDIT_2:

inputfile = "/some/file.json"
outputfile = "/some/file.csv"
with open(inputfile, 'r') as inf:
    with open(outputfile, 'w') as outf:
        writer = None  # will be set to a csv.DictWriter later
            fp = open(inputfile, 'r')
            json_value = fp.read()
            data = json.loads(json_value)

        for key, item in sorted(data.items(), key=itemgetter(0)):
            row = {}
            nested_name, nested_items = '', {}
            for k, v in item.items():
                if not isinstance(v, dict):
                    row[k] = v
                else:
                    assert not nested_items, 'Only one nested structure is supported'
                    nested_name, nested_items = k, v

            if writer is None:
                # build fields for each first key of each nested item first
                fields = sorted(row)

                # sorted keys of first item in key sorted order
                nested_keys = sorted(sorted(nested_items.items(), key=itemgetter(0))[0][1])
                fields.extend('__'.join((nested_name, k)) for k in nested_keys)

                writer = csv.DictWriter(outf, fields)
                writer.writeheader()

            for nkey, nitem in sorted(nested_items.items(), key=itemgetter(0)):
                row.update(('__'.join((nested_name, k)), v) for k, v in nitem.items())
                writer.writerow(row)

我得到的错误是......

for k, v in item.items():

AttributeError: 'list' 对象没有属性 'items'

我想我可能没有正确读取 JSON 文件...Python 新手压力源。

EDIT_3(更新的 JSON 结构): 这是我正在使用的 JSON 文件(NIST/NVD JSON 文件)中的一个“条目”:

    {
      "CVE_data_type" : "CVE",
      "CVE_data_format" : "MITRE",
      "CVE_data_version" : "4.0",
      "CVE_data_numberOfCVEs" : "6208",
      "CVE_data_timestamp" : "2017-08-14T18:06Z",
      "CVE_Items" : [ {
        "cve" : {
          "CVE_data_meta" : {
            "ID" : "CVE-2003-1547"
          },
          "affects" : {
            "vendor" : {
              "vendor_data" : [ {
                "vendor_name" : "francisco_burzi",
                "product" : {
                  "product_data" : [ {
                    "product_name" : "php-nuke",
                    "version" : {
                      "version_data" : [ {
                        "version_value" : "6.5"
                      }, {
                        "version_value" : "6.5_beta1"
                      }, {
                        "version_value" : "6.5_rc3"
                      }, {
                        "version_value" : "6.5_rc2"
                      }, {
                        "version_value" : "6.5_rc1"
                      } ]
                    }
                  } ]
                }
              } ]
            }
          },
          "problemtype" : {
            "problemtype_data" : [ {
              "description" : [ {
                "lang" : "en",
                "value" : "CWE-79"
              } ]
            } ]
          },
          "references" : {
            "reference_data" : [ {
              "url" : "http://secunia.com/advisories/8478"
            }, {
              "url" : "http://securityreason.com/securityalert/3718"
            }, {
              "url" : "http://www.securityfocus.com/archive/1/archive/1/316925/30/25250/threaded"
            }, {
              "url" : "http://www.securityfocus.com/archive/1/archive/1/317230/30/25220/threaded"
            }, {
              "url" : "http://www.securityfocus.com/bid/7248"
            }, {
              "url" : "https://exchange.xforce.ibmcloud.com/vulnerabilities/11675"
            } ]
          },
          "description" : {
            "description_data" : [ {
              "lang" : "en",
              "value" : "Cross-site scripting (XSS) vulnerability in block-Forums.php in the Splatt Forum module for PHP-Nuke 6.x allows remote attackers to inject arbitrary web script or HTML via the subject parameter."
            } ]
          }
        },
        "configurations" : {
          "CVE_data_version" : "4.0",
          "nodes" : [ {
            "operator" : "OR",
            "cpe" : [ {
              "vulnerable" : true,
              "cpeMatchString" : "cpe:/a:francisco_burzi:php-nuke:6.5",
              "cpe23Uri" : "cpe:2.3:a:francisco_burzi:php-nuke:6.5:*:*:*:*:*:*:*"
            }, {
              "vulnerable" : true,
              "cpeMatchString" : "cpe:/a:francisco_burzi:php-nuke:6.5_beta1",
              "cpe23Uri" : "cpe:2.3:a:francisco_burzi:php-nuke:6.5_beta1:*:*:*:*:*:*:*"
            }, {
              "vulnerable" : true,
              "cpeMatchString" : "cpe:/a:francisco_burzi:php-nuke:6.5_rc1",
              "cpe23Uri" : "cpe:2.3:a:francisco_burzi:php-nuke:6.5_rc1:*:*:*:*:*:*:*"
            }, {
              "vulnerable" : true,
              "cpeMatchString" : "cpe:/a:francisco_burzi:php-nuke:6.5_rc2",
              "cpe23Uri" : "cpe:2.3:a:francisco_burzi:php-nuke:6.5_rc2:*:*:*:*:*:*:*"
            }, {
              "vulnerable" : true,
              "cpeMatchString" : "cpe:/a:francisco_burzi:php-nuke:6.5_rc3",
              "cpe23Uri" : "cpe:2.3:a:francisco_burzi:php-nuke:6.5_rc3:*:*:*:*:*:*:*"
            } ]
          } ]
        },
        "impact" : {
          "baseMetricV2" : {
            "cvssV2" : {
              "vectorString" : "(AV:N/AC:M/Au:N/C:N/I:P/A:N)",
              "accessVector" : "NETWORK",
              "accessComplexity" : "MEDIUM",
              "authentication" : "NONE",
              "confidentialityImpact" : "NONE",
              "integrityImpact" : "PARTIAL",
              "availabilityImpact" : "NONE",
              "baseScore" : 4.3
            },
            "severity" : "MEDIUM",
            "exploitabilityScore" : 8.6,
            "impactScore" : 2.9,
            "obtainAllPrivilege" : false,
            "obtainUserPrivilege" : false,
            "obtainOtherPrivilege" : false,
            "userInteractionRequired" : true
          }
        },
        "publishedDate" : "2003-12-31T05:00Z",
        "lastModifiedDate" : "2017-08-08T01:29Z"
      }]
}

我希望键是 CSV 文件的标题(如 lastModifiedDate、cpe23Uri 等)。一旦我在 CSV 文件中有标题和数据,我就可以过滤掉空白并只选择我想要的列。

【问题讨论】:

  • @MartjinPieters...您回答了链接的问题...您也可以回答这个问题吗? :p
  • 该问题假设您已经在列表中拥有数据,您可以通过任何方式获取数据。它不必来自输入文件,它可以来自您执行的计算。
  • 如果您想从另一个文件中获取它,只需编写代码以打开该文件并以任何合适的方式对其进行解析。
  • 链接的问题或答案中没有显示,但我认为假设 JSON 数据已加载到名为 data 的 Python 字典中。这可以通过data = json.load(fp) 之类的东西来完成,其中fp 是一个.read()-支持包含JSON 文档的类文件对象。
  • @martineau - 感谢您的指导。我现在遇到错误。贴在上面。

标签: python json python-3.x csv export-to-csv


【解决方案1】:

幸运的是,您的 JSON 数据足够有效,json.load() 可以读取和解析......但只是说您希望键成为标题还不够具体——每个 ' 的不同级别都有很多键条目”(如下所示)。请注意,链接问题的 OP 不仅定义了输入,而且还具体定义了其中的数据如何映射到 CSV 文件中的值列,该文件的格式也显示出来——而不仅仅是一些关于映射键的挥手到文件头。

无论如何,这里有一些东西可以帮助你做到这一点。它将读取列表中与您正在读取的 JSON 对象中的顶级 "CVE_Items" 键关联的每个“条目”,并将其打印出来并格式化。从输出中,您应该能够挑选出要提取的列并将其作为行写入 CSV 文件,并且可以填写执行此操作的代码。

import json

inputfile = "some_file.json"
outputfile = "some_file.csv"

with open(outputfile, 'w', newline='') as outf:
    with open(inputfile, 'r') as fp:
        data = json.load(fp)

    # Here is where you should convert each entry into a row of CSV data.
    # All this does now is show the contents of each entry in "CVE_Items" list.
    for entry in data["CVE_Items"]:
        print(json.dumps(entry, indent=4))

您添加到问题的示例 JSON 数据中的单个条目的输出:

{
    "cve": {
        "CVE_data_meta": {
            "ID": "CVE-2003-1547"
        },
        "affects": {
            "vendor": {
                "vendor_data": [
                    {
                        "vendor_name": "francisco_burzi",
                        "product": {
                            "product_data": [
                                {
                                    "product_name": "php-nuke",
                                    "version": {
                                        "version_data": [
                                            {
                                                "version_value": "6.5"
                                            },
                                            {
                                                "version_value": "6.5_beta1"
                                            },
                                            {
                                                "version_value": "6.5_rc3"
                                            },
                                            {
                                                "version_value": "6.5_rc2"
                                            },
                                            {
                                                "version_value": "6.5_rc1"
                                            }
                                        ]
                                    }
                                }
                            ]
                        }
                    }
                ]
            }
        },
        "problemtype": {
            "problemtype_data": [
                {
                    "description": [
                        {
                            "lang": "en",
                            "value": "CWE-79"
                        }
                    ]
                }
            ]
        },
        "references": {
            "reference_data": [
                {
                    "url": "http://secunia.com/advisories/8478"
                },
                {
                    "url": "http://securityreason.com/securityalert/3718"
                },
                {
                    "url": "http://www.securityfocus.com/archive/1/archive/1/316925/30/25250/threaded"
                },
                {
                    "url": "http://www.securityfocus.com/archive/1/archive/1/317230/30/25220/threaded"
                },
                {
                    "url": "http://www.securityfocus.com/bid/7248"
                },
                {
                    "url": "https://exchange.xforce.ibmcloud.com/vulnerabilities/11675"
                }
            ]
        },
        "description": {
            "description_data": [
                {
                    "lang": "en",
                    "value": "Cross-site scripting (XSS) vulnerability in block-Forums.php in the Splatt Forum module for PHP-Nuke 6.x allows remote attackers to inject arbitrary web script or HTML via the subject parameter."
                }
            ]
        }
    },
    "configurations": {
        "CVE_data_version": "4.0",
        "nodes": [
            {
                "operator": "OR",
                "cpe": [
                    {
                        "vulnerable": true,
                        "cpeMatchString": "cpe:/a:francisco_burzi:php-nuke:6.5",
                        "cpe23Uri": "cpe:2.3:a:francisco_burzi:php-nuke:6.5:*:*:*:*:*:*:*"
                    },
                    {
                        "vulnerable": true,
                        "cpeMatchString": "cpe:/a:francisco_burzi:php-nuke:6.5_beta1",
                        "cpe23Uri": "cpe:2.3:a:francisco_burzi:php-nuke:6.5_beta1:*:*:*:*:*:*:*"
                    },
                    {
                        "vulnerable": true,
                        "cpeMatchString": "cpe:/a:francisco_burzi:php-nuke:6.5_rc1",
                        "cpe23Uri": "cpe:2.3:a:francisco_burzi:php-nuke:6.5_rc1:*:*:*:*:*:*:*"
                    },
                    {
                        "vulnerable": true,
                        "cpeMatchString": "cpe:/a:francisco_burzi:php-nuke:6.5_rc2",
                        "cpe23Uri": "cpe:2.3:a:francisco_burzi:php-nuke:6.5_rc2:*:*:*:*:*:*:*"
                    },
                    {
                        "vulnerable": true,
                        "cpeMatchString": "cpe:/a:francisco_burzi:php-nuke:6.5_rc3",
                        "cpe23Uri": "cpe:2.3:a:francisco_burzi:php-nuke:6.5_rc3:*:*:*:*:*:*:*"
                    }
                ]
            }
        ]
    },
    "impact": {
        "baseMetricV2": {
            "cvssV2": {
                "vectorString": "(AV:N/AC:M/Au:N/C:N/I:P/A:N)",
                "accessVector": "NETWORK",
                "accessComplexity": "MEDIUM",
                "authentication": "NONE",
                "confidentialityImpact": "NONE",
                "integrityImpact": "PARTIAL",
                "availabilityImpact": "NONE",
                "baseScore": 4.3
            },
            "severity": "MEDIUM",
            "exploitabilityScore": 8.6,
            "impactScore": 2.9,
            "obtainAllPrivilege": false,
            "obtainUserPrivilege": false,
            "obtainOtherPrivilege": false,
            "userInteractionRequired": true
        }
    },
    "publishedDate": "2003-12-31T05:00Z",
    "lastModifiedDate": "2017-08-08T01:29Z"
}

【讨论】:

  • 感谢您提供的代码。我可以像你上面显示的那样打印。如何将其展平成可以写入 CSV 文件的行?
  • 我不知道如何将其展平。正如我所说,在链接的问题中,OP 指定了 JSON 数据的各个部分如何转换为 CSV 行。 JSON 主要是一种树数据结构,而 CSV 是一个表(或 2D 数组/矩阵),从一个到另一个的映射是任意的。我无法决定如何为你做这部分——但如果你至少可以定义你想要什么,我可能会向你展示如何实现它。一个非常重要的细节是,具有多个关联值的东西(例如 "version_data")如何变成单行。
  • JSON 文件中的数据似乎在一个 key:value 对中,有时对于给定的 key 有多个值,如上面的“version_data:”。我想让对的“键”部分成为列的标题,而“值”作为数据填充到列中。在一个键有多个值的情况下,我需要连接给定键的所有值。
  • 也许最简单的方式来描述您想要的内容是 edit 您的问题并显示您希望从示例 JSON 数据中的单个“条目”创建的单个 CSV 行。跨度>
  • 我不能在我上面提出的问题中添加 CSV 行(没有足够的声誉点),也不能发表评论(太长了几千个字符)。有什么建议吗?
猜你喜欢
  • 2013-12-23
  • 2019-06-30
  • 2021-08-31
  • 2020-10-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-20
相关资源
最近更新 更多