2017-08-17 4 views
-1

Die neu in Python, und angesichts der Antwort auf folgende Beitrag schreiben:verschachtelte JSON parsen und zu CSV (Revisited)

Parsing nested JSON and writing it to CSV

Wie definiere ich die Eingabedatei für diesen Code zu arbeiten? Ich verstehe, dass ich die "Ausgabedatei" als den Pfad/den Dateinamen definieren muss, zu dem ich schreibe, aber ich weiß nur nicht, wohin die Eingabedatei gehen soll?

EDIT: Hinzufügen für die Klarheit, dass ich eine JSON-Datei für die Eingabe habe und es in eine CSV-Datei als Ausgabe konvertieren möchte. Ich möchte nur wissen, wie man den Code schreibt, der das Beispiel (von oben) nehmen und eine bestimmte JSON-Datei als Eingabe angeben würde. Der Übersichtlichkeit halber wird der Name der JSON-Datei gleich bleiben, aber der Inhalt wird sich täglich ändern, also muss ich nur wissen, wo ich die open() einfügen soll und wie ich sie im Skript aufrufen soll.

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) 

Der Fehler, den ich bekommen habe ist ...

for k, v in item.items(): 

Attribute: 'list' Objekt hat kein Attribut 'Elemente'

Ich glaube, ich kann nicht Lesen Sie die JSON-Datei korrekt ... Python-Newbie-Stressoren.

EDIT_3 (aktualisiert JSON-Struktur): Hier wird ein 'Eintrag' aus der JSON-Datei I (NIST/NVD JSON-Datei) bin mit:

{ 
     "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" 
     }] 
} 

ich den Schlüssel möchte die Header sein (wie lastModifiedDate, cpe23Uri, etc) für die CSV-Datei. Ich kann Leerraum herausfiltern und nur die Spalten auswählen, die ich möchte, sobald ich die Header und Daten in der CSV-Datei habe.

+0

@MartjinPieters ... Sie die verknüpfte Frage beantwortet ... Sie diese auch beantworten können? : p –

+0

Bei dieser Frage wird davon ausgegangen, dass Sie die Daten bereits in einer Liste haben. Sie können die Daten nach Belieben abrufen. Es muss nicht aus einer Eingabedatei stammen, es kann aus Berechnungen stammen, die Sie ausführen. – Barmar

+0

Wenn Sie es aus einer anderen Datei abrufen möchten, schreiben Sie einfach Code, um diese Datei zu öffnen und sie auf die jeweils geeignete Weise zu parsen. – Barmar

Antwort

0

Zum Glück sind Ihre JSON-Daten gültig genug für json.load() zu lesen und zu analysieren .... aber nur zu sagen, Sie möchten, dass die Schlüssel die Header sind, ist nicht spezifisch genug - es gibt viele von ihnen auf verschiedenen Ebenen jedes Eintrags "(wie Sie unten sehen werden). Beachten Sie, dass das OP der verknüpften Frage nicht nur die Eingabe definierte, sondern auch speziell, wie die darin enthaltenen Daten in einer CSV-Datei in einem Format, das auch angezeigt wird, auf Wertespalten abgebildet werden sollten - nicht nur einige Handbewegungen über Zuordnungsschlüssel zu Dateiheadern.

Unabhängig davon, hier ist etwas, das Ihnen dabei helfen kann. Es liest jeden 'Eintrag' in der Liste, die dem obersten Schlüssel "CVE_Items" im JSON-Objekt zugeordnet ist, das Sie gerade lesen, und druckt es gut formatiert aus. Aus der Ausgabe sollten Sie in der Lage sein, die Spalten auszuwählen, die Sie extrahieren und als Zeilen in die CSV-Datei schreiben möchten, und Sie können den Code dafür eingeben.

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)) 

Ausgang für den einzelnen Eintrag in der Probe JSON Daten, die Sie auf Ihre Frage hinzugefügt:

{ 
    "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" 
} 
+0

danke für diesen Code. Ich kann drucken, wie Sie oben zeigen. Wie mache ich das in eine Zeile, die ich in eine CSV-Datei schreiben kann? –

+0

Ich weiß nicht, wie man es glättet. Wie gesagt, in der verknüpften Frage hat das OP festgelegt, wie die verschiedenen Teile der JSON-Daten in CSV-Zeilen umgewandelt werden sollen. JSON ist hauptsächlich eine Baumdatenstruktur, während CSV eine Tabelle (oder 2D-Array/Matrix) ist und die Zuordnung von einem zum anderen beliebig ist. Ich kann mich nicht entscheiden, wie ich diesen Teil für Sie tun soll - aber wenn Sie zumindest definieren könnten, was Sie wollen, könnte ich Ihnen wahrscheinlich zeigen, wie Sie es umsetzen können. Ein sehr wichtiges Detail ist, wie etwas, das mehrere Werte hat, wie "version_data", in eine einzelne Zeile umgewandelt wird. – martineau

+0

Es scheint, dass die Daten in der JSON-Datei in einem Schlüssel: Wert-Paar, manchmal mit mehr als einem Wert für den angegebenen Schlüssel, wie in "version_data:" oben. Ich möchte, dass der "Schlüssel" -Teil des Paares die Kopfzeile für die Spalte ist und der "Wert" (die Werte) die Spalte als Daten ausfüllen. Im Fall von mehreren Werten für einen Schlüssel muss ich alle Werte für den gegebenen Schlüssel verketten. –