Zum Inhalt

Kurze Einführung in das Parsen von JSON mit JSONPath in Python

JSON ist zum De-facto-Standard für den Datenaustausch im Web geworden. APIs, Webdienste und moderne Websites nutzen JSON häufig zum Senden von Daten zwischen Servern und Clients.

Laut BuiltWith verwenden beispielsweise über 70 % der Top-10,000-Websites JSON-APIs. Das JSON-Format lässt sich in jeder Programmiersprache einfach generieren und analysieren.

Das effiziente Extrahieren aussagekräftiger Informationen aus großen JSON-Dokumenten kann jedoch immer noch eine Herausforderung sein. Hier kommt JSONPath ins Spiel – eine spezielle Abfragesprache, die das Auffinden und Transformieren von JSON-Daten vereinfacht.

Das Problem beim Parsen von JSON

Traditionell werden JSON-Daten in Anwendungen verarbeitet, indem sie vollständig in native Datenstrukturen wie Python-Dikte analysiert werden. Sie würden die gesamte JSON-Antwort analysieren, selbst wenn Sie nur eine kleine Teilmenge der Daten benötigen würden.

Dieser Ansatz hat einige Nachteile:

  • Geringe Leistung – Das Parsen großer JSON-Dateien in Objekte ist rechenintensiv
  • Hohe Speicherauslastung – Die gesamte JSON-Struktur muss im Speicher gehalten werden
  • Ausführlicher Code – Sie müssen oft viel Schleifen-/Traversalcode schreiben, um in die analysierten Objekte einzudringen

Eine Alternative besteht darin, reguläre Ausdrücke zu verwenden, um passende JSON-Fragmente direkt zu extrahieren. Allerdings wird Regex bei komplexen verschachtelten Strukturen unübersichtlich. Es hat auch Probleme mit dynamischen Schlüsselnamen oder willkürlichen Verschachtelungstiefen.

JSONPath bietet eine sauberere und präzisere Möglichkeit, JSON im Vergleich zum Rohparsing oder Regex-Abgleich abzufragen.

Einführung in JSONPath

JSONPath-Ausdrücke beschreiben, wie auf Teile eines JSON-Dokuments zugegriffen wird. Vom Konzept her ähnelt es XPath, das die Abfrage von Elementen und Attributen in XML ermöglicht:

//node/child::*  - XPath for all child nodes
$.node.child     - Equivalent JSONPath 

Einige Vorteile des JSONPath-Ansatzes:

  • Ablesbarkeit – Abfrageausdrücke sind leicht zu verstehen
  • Kürze – Kein ausführlicher Traversalcode erforderlich
  • Flexibilität – Unterstützt Suchvorgänge, Filter und Platzhalterübereinstimmungen
  • Leistung – Sehr optimierte Matching-Algorithmen
  • Skalierbarkeit – Kann selbst große JSON-Dokumente schnell verarbeiten

JSONPath bietet eine einfache, skalierbare Alternative zum Extrahieren von Daten aus JSON. Schauen wir uns als nächstes an, wie es funktioniert.

JSON mit JSONPath abfragen

Ein JSONPath-Ausdruck ist eine Zeichenfolge, die beschreibt, wie Werte innerhalb einer JSON-Struktur gefunden werden. Zum Beispiel:

data = {
  "store": {
    "books": [
      { "category": "reference",
        "author": "Nigel Rees",
        "title": "Sayings of the Century",
        "price": 8.95
      },
      { "category": "fiction",
        "author": "Evelyn Waugh",
        "title": "Sword of Honour",
        "price": 12.99
      }
    ]
  }
}

# All book titles
books = jsonpath(data, ‘$.store.books[*].title‘) 

# Filter fiction books 
fiction_books = jsonpath(data, ‘$.store.books[?(@.category=="fiction")].title‘)

JSONPath verwendet Operatoren wie:

  • . – Untergeordneter Operator
  • [] – Indexoperator für Array-Zugriff
  • * – Platzhalter für alle passenden Elemente
  • ?() – Prädikate filtern

Die Verkettung dieser Elemente ermöglicht eine effiziente Abfrage in komplexem JSON:

# Get all authors of books over 10 dollars 
authors = jsonpath(data, ‘$.store.books[?(@.price > 10)].author‘)

Kein tief verschachtelter Schleifencode mehr! JSONPath gleicht Objekte direkt ab, ohne dass der gesamte JSON-Baum vollständig analysiert werden muss.

Verfügbare JSONPath-Operatoren

Hier ist eine Zusammenfassung der in JSONPath verfügbaren Operatoren:

Pfadoperatoren

  • $ – Root-Objekt
  • @ – Aktuelles Objekt
  • . or [] – Untergeordneter Operator
  • .. – Nachkommen rekursiv suchen

Filteroperatoren

  • [?(<expression>)]– Objekte filtern
  • [(<condition>)]– Filtern Sie nach Bedingung

Array-Operatoren

  • * – Wildcard indiziert alle Elemente
  • [<index>] – Indexposition
  • [start:end] – Array-Slice
  • [?(<condition>)] – Filtern

Operatoren für die Projektion

  • [] – Projektion – Extrahiert aufgelistete Eigenschaften
  • [@] – Indexprojektion – Reduziert Arrays

Andere Betreiber

  • | – Gewerkschaftsbetreiber
  • () – Vorrangiger Betreiber
  • , – Trennt mehrere Ergebnisse

Diese bieten Ihnen umfassende Flexibilität beim Abfragen, Filtern und Transformieren von JSON-Daten mithilfe einfacher Pfadzeichenfolgen.

JSONPath vs. XPath für XML

Da JSONPath viele Ähnlichkeiten mit XPath aufweist, lohnt es sich, die beiden zu vergleichen:

XPath

  • Abfragesprache für XML
  • Ermöglicht das Durchlaufen des XML-Baums
  • Unterstützt erweiterte Achsen wie //, /*, //@
  • Zum Extrahieren von XML-Knoten verwenden

JSONPfad

  • Äquivalente Abfragesprache für JSON
  • Von XPath inspirierte Syntax
  • Einfachere Syntax, da JSON darstellungstechnisch einfacher ist als XML
  • Schnelle Implementierung, da kein XML-Parsing erforderlich ist

Beide ermöglichen die Auswahl von Knoten in hierarchischen Datenstrukturen. JSONPath könnte als vereinfachte Version von XPath betrachtet werden, die eher auf JSON als auf XML spezialisiert ist.

JSONPath wurde für viele Programmiersprachen implementiert. Einige beliebte Bibliotheken für Python sind:

BibliothekBeschreibung
jsonpath-ngEmpfohlene Bibliothek, schnell mit erweiterten Funktionen
jsonpath-rwKonforme Referenzimplementierung
jsonpathEinfache Implementierung, aber eingeschränkte Funktionen

Für die meisten Anwendungen, jsonpath-ng bietet die beste Kombination aus Compliance, Funktionen und Leistung.

Sehen wir uns die Verwendung genauer an.

Abfragen und Filtern mit jsonpath-ng

Installieren Sie zunächst jsonpath-ng:

pip install jsonpath-ng

Importieren:

from jsonpath_ng import jsonpath, parse

Einige Beispiele:

data = { "name": "John",
          "age": 30,
          "cars": [
            { "model": "BMW", "year": 2019 },
            { "model": "Tesla", "year": 2020 } 
          ]
        }

# Extract name
name = jsonpath(data, ‘$.name‘)

# Get first car 
first_car = jsonpath(data, ‘$.cars[0]‘)

# Filter Tesla cars
teslas = jsonpath(data, ‘$.cars[?(@.model=="Tesla")]‘) 

# Get all car years 
years = jsonpath(data, ‘$..cars[*].year‘)

Sie können auch die Tasten parse() Methode, die den Pfad für eine bessere Leistung kompiliert:

parser = parse(‘$.cars[*].year‘)

for obj in json_data:
   years = parser.find(obj)
   print(years)

Dies funktioniert schneller, wenn derselbe Pfad auf mehrere JSON-Dokumente angewendet wird.

JSON-Daten filtern

Eine der leistungsstärksten Funktionen von JSONPath ist seine Filtersyntax.

Filter ermöglichen die Auswahl von Objekten, die bestimmten Kriterien entsprechen. Zum Beispiel:

RecentCars = jsonpath(data, ‘$.cars[?(@.year > 2015)]‘)

Dadurch werden Autos neuer als 2015.

Sie können mithilfe von Vergleichen filtern wie:

  • Mathematisch: =, !=, >, <=, usw.
  • Logisch: and, or, not
  • Reguläre Ausdrücke: =~, !=~
  • Existenz: exists(), ?()

Filter können auch kombiniert werden:

ElectricCars = jsonpath(data, 
   ‘$.cars[?(@.year > 2010 && @.model =~ "Tesla|Volt")]`
)

Damit werden Elektroautos hergestellt, die nach 2010 hergestellt werden.

JSON-Daten transformieren

Neben dem Extrahieren von Daten kann JSONPath JSON-Objekte mithilfe von Operatoren wie den folgenden transformieren:

  • [] – Projektion zur Umformung von Objekten
  • [@] – Array-Indizierung zum Reduzieren

Reduzieren Sie beispielsweise Fahrzeugdaten auf eine einfache Liste:

all_models = jsonpath(data, ‘$..cars[*].model‘)
all_years = jsonpath(data, ‘$..cars[*].@year‘) 

Das @ führt eine indexbasierte Projektion durch.

Die Verkettung von Filtern, Projektionen und Slices ermöglicht die programmgesteuerte Umstrukturierung von JSON.

Erweiterte Funktionen von jsonpath-ng

Einige zusätzliche erweiterte Funktionen von jsonpath-ng:

Benutzerdefinierte Funktionen

Sie können benutzerdefinierte Funktionen registrieren, um JSONPath zu erweitern:

def format_price(x):
  return f‘${x:,.2f}‘

jsonpath.register_custom_function(format_price, ‘format‘)

prices = jsonpath(data, ‘$.prices[*].format(@)‘) 

Dies ermöglicht die Implementierung komplexer Datentransformationen direkt in JSONPath-Ausdrücken.

Caching und Optimierung

jsonpath-ng kompiliert und optimiert Abfragen für die Leistung. Es unterstützt auch:

  • Caching für Geschwindigkeit
  • Lazy Matching, um unnötige Scans zu vermeiden
  • Optimierung der Ausbringungsausbeute

Es funktioniert also auch bei großen JSON-Dokumenten gut.

Zusätzliche Operatoren

Einige andere nützliche Operatoren:

  • ?() – Existenzprüfung
  • =~, !=~ – Regex-Matching
  • in – Enthält Scheck
  • all – Universeller Quantor

JSONPath-Methoden

Hilfsmethoden wie:

  • find() – Gibt Übereinstimmungen zurück
  • parse() – Kompiliert den Pfad

Stellen Sie eine einfachere API für häufige Abfragen bereit.

Verwendung von JSONPath für Web Scraping

Eine der nützlichsten Anwendungen von JSONPath ist das Extrahieren von Daten beim Web Scraping.

Moderne Websites verlassen sich bei der Datenübertragung stark auf JSON:

  • APIs – JSON ist das Standardformat für REST-APIs
  • Asynchrone Daten – JSON wird mit JavaScript für dynamische Seitenaktualisierungen verwendet
  • Seitenmetadaten – Site-Daten werden oft in Skripten als JSON gespeichert

Das manuelle Parsen dieses gesamten JSON-Codes wäre umständlich. Mit JSONPath können Sie ganz einfach nur die Fragmente abfragen, die Sie benötigen.

So extrahieren Sie beispielsweise Produktdaten von einer E-Commerce-Seite:

import requests
from jsonpath_ng import jsonpath, parse

# Fetch product page
url = "http://www.example.com/product/123"  
response = requests.get(url)

# Extract JSON data 
data = response.json()

# Parse out product details 
name = jsonpath(data, ‘$.product.name‘)[0]
price = jsonpath(data, ‘$.product.price‘)[0] 
image = jsonpath(data, ‘$.product.images[0]‘)

print(name, price, image)

Der Schlüssel liegt darin, JSONPath zu verwenden, um direkt nur die benötigten Felder zu erfassen, anstatt sie manuell zu verarbeiten.

Hier sind einige häufige Anwendungsfälle:

  • API-Scraping – Extrahieren Sie Daten aus REST-API-Antworten
  • JavaScript-Sites – Abfrageobjekte, die von Frontends verwendet werden
  • Mobile Apps – Analysieren Sie JSON-Daten aus dem App-Verkehr
  • Dynamischer Inhalt – Erstellen Sie Datensätze aus clientseitigem JavaScript

JSONPath ermöglicht das skalierbare Scraping von Tausenden von JSON-Dokumenten mit einfachen Pfadzeichenfolgen.

Parsen großer JSON-Dateien

Obwohl sich JSONPath gut skalieren lässt, kann das Parsen großer JSON-Dokumente dennoch eine Herausforderung darstellen:

  • Speichernutzung – Laden des vollständigen JSON in den Speicher
  • CPU-Last – Das Parsen komplexer Dokumente ist prozessorintensiv
  • Netzwerkübertragung – Große Dokumente bedeuten mehr Bandbreite

Einige Tipps für die Arbeit mit großen JSON-Daten:

  • Verwenden Sie Streaming-Parser, um ein vollständiges Laden von JSON zu vermeiden
  • Kompilieren Sie Pfade mit parse() statt erneut zu analysieren
  • Extrahieren Sie nur die tatsächlich benötigten Felder anstelle vollständiger Objekte
  • Verwenden Sie die laziness um unnötige Objektscans zu vermeiden
  • Führen Sie bei der Verarbeitung von Daten im TB+-Bereich auf leistungsstarken Cloud-Servern aus
  • Verteilen Sie das Parsing für eine parallele Verarbeitung auf Cluster

In den meisten Fällen kann JSONPath bei richtiger Optimierung Daten selbst aus riesigen JSON-Dateien mit Hunderttausenden Datensätzen effizient extrahieren.

Warum ich JSONPath liebe

Als erfahrener Proxy-Ingenieur, der intensiv mit JSON-Daten arbeitet, verwende ich JSONPath aus folgenden Gründen so gern:

  • Prägnante Syntax – Pfadausdrücke sind im Vergleich zu herkömmlichem Parsing-Code wunderbar prägnant
  • Erhöhte Produktivität – Dank der intuitiven Syntax können Sie JSON genauso einfach abfragen wie eine Datenbank
  • Robuste Filterung – Die Prädikatfilter machen die Auswahl passender Daten zum Kinderspiel
  • Blitzschnelle Leistung – jsonpath-ng verwendet extrem optimierte Algorithmen unter der Haube, die eine blitzschnelle Datenextraktion auch bei großen Datenmengen ermöglichen
  • Speichereffizient – Da JSON selektiv analysiert wird, ist der Speicherbedarf im Vergleich zur vollständigen Analyse nativer Objekte gering
  • Web-Scraping-Leistung – Durch die einfache Datenextraktion aus APIs und JavaScript-Antworten glänzt JSONPath

Während Tools wie jq und grep großartig sind, finde ich JSONPath für die meisten meiner JSON-Parsing-Anforderungen einfacher und eleganter. Die Unterstützung des Python-Ökosystems mit Bibliotheken wie jsonpath-ng macht es zu meiner ersten Wahl für das Slicing und Dicing von JSON-Daten.

JSONPath-Unterstützung in anderen Sprachen

Während wir uns auf Python konzentriert haben, ist JSONPath in vielen Programmiersprachen verfügbar:

Da es sich bei JSON um ein universelles Datenformat handelt, ist es hilfreich, es aus jeder Sprache effizient abfragen zu können. Zum Glück wird JSONPath weitgehend unterstützt.

Warum JSONPath wichtig ist

JSON ist für Web-APIs, Microservices und Front-End-Anwendungen schnell unverzichtbar geworden. JSONPath bringt XPath-ähnliche Abfragefunktionen in die Welt der JSON-Daten.

Eine standardisierte Pfadsprache zum einfachen Extrahieren verschachtelter JSON-Werte hat viele Vorteile:

  • Vereinfacht die JSON-Datenextraktion über Plattformen und Sprachen hinweg
  • Bietet eine lesbare Alternative zum hässlichen Regex-Parsing
  • Ermöglicht skalierbares Web-Scraping, ohne dass ganze Antworten analysiert werden müssen
  • Ermöglicht komplexe Transformationen mithilfe von Projektionen und Filtern
  • Schaltet die Möglichkeit frei, große JSON-Datensätze effizient abzufragen
  • Passt natürlich in Pipelines zusammen mit anderen JSON-Tools wie jq

Während JSON seine Dominanz als De-facto-Datenaustauschformat fortsetzt, wird die Verwendung einer Reihe gemeinsamer JSONPath-Operatoren dazu beitragen, die Komplexität der Navigation in großen JSON-Dokumenten zu begrenzen.

Zusammenfassung

JSONPath bietet eine elegante Möglichkeit, Werte aus JSON-Daten durch prägnante Pfadausdrücke zu extrahieren und zu transformieren.

Bibliotheken wie jsonpath-ng Machen Sie die Integration von JSONPath in Ihre Python-Projekte einfach.

Die zentralen Thesen:

  • JSONPath ermöglicht die einfache Abfrage von JSON-Strukturen mithilfe von „.“ und „[]“-Operatoren
  • Das Filtern nach Eigenschaftswerten mithilfe von Prädikaten lässt sich gut skalieren
  • Transformationen können mithilfe von Projektionen und Array-Erweiterungen angewendet werden
  • JSONPath vermeidet die Notwendigkeit, beim Scraping ganze JSON-Objekte zu analysieren
  • Die Syntax ist XPath-Ausdrücken zum Abfragen von XML nachempfunden
  • Unterstützt in vielen Programmiersprachen

Für die Arbeit mit JSON-basierten Webdiensten ist JSONPath ein unverzichtbares Werkzeug im Toolkit jedes Entwicklers. Mit JSONPath können Sie einfache Fragen stellen und aus komplexen JSON-Dokumenten genau die Daten abrufen, die Sie benötigen.

Stichworte:

Mitreden

E-Mail-Adresse wird nicht veröffentlicht. Pflichtfelder sind MIT * gekennzeichnet. *