Meteen naar de inhoud

Snelle introductie tot het parseren van JSON met JSONPath in Python

JSON is de de facto standaard geworden voor gegevensuitwisseling op internet. API's, webservices en moderne websites maken op grote schaal gebruik van JSON voor het verzenden van gegevens tussen servers en clients.

Volgens BuiltWith gebruikt bijvoorbeeld meer dan 70% van de top 10,000 websites JSON API's. Het JSON-formaat is eenvoudig te genereren en te parseren in elke programmeertaal.

Het efficiënt extraheren van betekenisvolle informatie uit grote JSON-documenten kan echter nog steeds een uitdaging zijn. Dit is waar JSONPath in beeld komt: een gespecialiseerde querytaal die de manier vereenvoudigt waarop u JSON-gegevens lokaliseert en transformeert.

Het probleem met het parseren van JSON

Traditioneel worden JSON-gegevens in applicaties verwerkt door deze volledig te parseren in native datastructuren zoals Python-dicts. U zou het volledige JSON-antwoord parseren, zelfs als u slechts een kleine subset van de gegevens nodig had.

Deze aanpak heeft enkele nadelen:

  • Slow prestaties – Het parseren van grote JSON-bestanden in objecten is rekentechnisch duur
  • Hoog geheugengebruik – De gehele JSON-structuur moet in het geheugen worden bewaard
  • Uitgebreide code – Je moet vaak veel looping/traversal-code schrijven om in de geparseerde objecten te kunnen graven

Een alternatief is het gebruik van reguliere expressies om overeenkomende JSON-fragmenten direct te extraheren. Regex wordt echter rommelig met complexe geneste structuren. Het worstelt ook met dynamische sleutelnamen of willekeurige nestdieptes.

JSONPath biedt een schonere en beknoptere manier om JSON te bevragen in vergelijking met onbewerkte parsering of regex-matching.

Maak kennis met JSONPath

JSONPath-expressies beschrijven hoe u toegang krijgt tot delen van een JSON-document. Het is conceptueel vergelijkbaar met XPath, waarmee elementen en attributen in XML kunnen worden opgevraagd:

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

Enkele voordelen van de JSONPath-aanpak:

  • leesbaarheid – Query-expressies zijn gemakkelijk te begrijpen
  • Beknoptheid – Geen behoefte aan uitgebreide traversal-code
  • Flexibiliteit – Ondersteunt zoekopdrachten, filters, jokertekenovereenkomsten
  • Performance – Zeer geoptimaliseerde matching-algoritmen
  • Schaalbaarheid – Kan zelfs grote JSON-documenten snel verwerken

JSONPath biedt een eenvoudig, schaalbaar alternatief voor het extraheren van gegevens uit JSON. Laten we vervolgens eens kijken hoe het werkt.

JSON opvragen met JSONPath

Een JSONPath-expressie is een tekenreeks die beschrijft hoe waarden binnen een JSON-structuur kunnen worden gevonden. Bijvoorbeeld:

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 gebruikt operatoren zoals:

  • . – Kindoperator
  • [] – Subscript-operator voor array-toegang
  • * – Wildcard voor alle overeenkomende elementen
  • ?() – Predikaten filteren

Door deze aan elkaar te koppelen, kunnen er efficiënt query's worden uitgevoerd in complexe JSON:

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

Geen diep geneste luscode meer! JSONPath matcht objecten rechtstreeks zonder dat de volledige JSON-boom volledig hoeft te worden geparseerd.

Beschikbare JSONPath-operators

Hier is een samenvatting van de operators die beschikbaar zijn in JSONPath:

Padoperatoren

  • $ – Root-object
  • @ – Huidig ​​object
  • . or [] – Kindoperator
  • .. – Recursief zoeken naar nakomelingen

Filteroperatoren

  • [?(<expression>)]– Objecten filteren
  • [(<condition>)]– Filter op basis van voorwaarde

Matrix-operators

  • * – Wildcard indexeert alle elementen
  • [<index>] – Indexpositie
  • [start:end] – Array-segment
  • [?(<condition>)] – Filteren

Operatoren voor projectie

  • [] – Projectie – Extraheert vermelde eigenschappen
  • [@] – Indexprojectie – Maakt arrays plat

Andere operators

  • | – Vakbondsoperator
  • () – Prioritaire operator
  • , – Begrenst meerdere resultaten

Deze bieden u uitgebreide flexibiliteit bij het opvragen, filteren en transformeren van JSON-gegevens met behulp van eenvoudige padreeksen.

JSONPath versus XPath voor XML

Omdat JSONPath veel overeenkomsten vertoont met XPath, is het de moeite waard om de twee te vergelijken:

XPath

  • Querytaal voor XML
  • Maakt het mogelijk om de XML-boom te doorlopen
  • Ondersteunt geavanceerde assen zoals //, /*, //@
  • Gebruiken om XML-knooppunten te extraheren

JSONPath

  • Equivalente querytaal voor JSON
  • Syntaxis geïnspireerd door XPath
  • Eenvoudigere syntaxis omdat JSON representatief eenvoudiger is dan XML
  • Snelle implementatie omdat er geen XML-parsing nodig is

Beide maken het selecteren van knooppunten in hiërarchische datastructuren mogelijk. JSONPath kan worden beschouwd als een vereenvoudigde versie van XPath, gespecialiseerd voor JSON in plaats van XML.

JSONPath is voor veel programmeertalen geïmplementeerd. Enkele populaire bibliotheken voor Python zijn:

BibliotheekOmschrijving
jsonpath-ngAanbevolen bibliotheek, snel met geavanceerde functies
jsonpath-rwConforme referentie-implementatie
jsonpadEenvoudige implementatie maar beperkte functies

Voor de meeste toepassingen, jsonpath-ng biedt de beste combinatie van compliance, functies en prestaties.

Laten we in meer detail bekijken hoe u het kunt gebruiken.

Query's uitvoeren en filteren met jsonpath-ng

Installeer eerst jsonpath-ng:

pip install jsonpath-ng

Importeren:

from jsonpath_ng import jsonpath, parse

Een paar voorbeelden:

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

U kunt ook gebruik maken van de parse() methode die het pad compileert voor betere prestaties:

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

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

Dit werkt sneller wanneer hetzelfde pad op meerdere JSON-documenten wordt toegepast.

JSON-gegevens filteren

Een van de krachtigste functies van JSONPath is de filtersyntaxis.

Met filters kunt u objecten selecteren die aan specifieke criteria voldoen. Bijvoorbeeld:

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

Hierdoor worden auto's nieuwer dan 2015.

U kunt filteren met vergelijkingen zoals:

  • Wiskundig: =, !=, >, <=, Etc.
  • Logisch: and, or, not
  • Normale uitdrukkingen: =~, !=~
  • Bestaan: exists(), ?()

Filters kunnen ook worden gecombineerd:

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

Dit levert elektrische auto’s op die na 2010 zijn gemaakt.

JSON-gegevens transformeren

Naast het extraheren van gegevens kan JSONPath JSON-objecten transformeren met behulp van operators zoals:

  • [] – Projectie om objecten een nieuwe vorm te geven
  • [@] – Array-indexering om af te vlakken

Autogegevens samenvoegen tot een eenvoudige lijst:

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

De @ doet op index gebaseerde projectie.

Door filters, projecties en segmenten aan elkaar te koppelen, kunt u JSON programmatisch herstructureren.

Geavanceerde functies van jsonpath-ng

Enkele extra geavanceerde functies van jsonpath-ng:

Aangepaste functies

U kunt aangepaste functies registreren om JSONPath uit te breiden:

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

jsonpath.register_custom_function(format_price, ‘format‘)

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

Dit maakt het mogelijk om complexe gegevenstransformaties rechtstreeks binnen JSONPath-expressies te implementeren.

Caching en optimalisatie

jsonpath-ng compileert en optimaliseert queries voor prestaties. Het ondersteunt ook:

  • Caching voor snelheid
  • Lazy matching om onnodige scans te voorkomen
  • Optimalisatie van de outputopbrengst

Het presteert dus goed, zelfs tegen grote JSON-documenten.

Extra operators

Enkele andere handige operatoren:

  • ?() – Bestaanscontrole
  • =~, !=~ – Regex-matching
  • in – Bevat cheque
  • all – Universele kwantificator

JSONPath-methoden

Hulpmethoden zoals:

  • find() - Geeft overeenkomsten terug
  • parse() – Compileert pad

Bied een eenvoudigere API voor veelvoorkomende vragen.

JSONPath gebruiken voor webscraping

Een van de handigste toepassingen van JSONPath is het extraheren van gegevens bij webscrapen.

Moderne websites zijn sterk afhankelijk van JSON voor het verzenden van gegevens:

  • APIs – JSON is het standaardformaat voor REST API’s
  • Asynchrone gegevens – JSON wordt gebruikt met JavaScript voor dynamische pagina-updates
  • Metagegevens van pagina – Sitegegevens vaak opgeslagen in scripts als JSON

Het handmatig parseren van al deze JSON zou omslachtig zijn. Met JSONPath kunt u eenvoudig alleen de fragmenten opvragen die u nodig hebt.

Hier leest u bijvoorbeeld hoe u productgegevens uit een e-commercepagina kunt extraheren:

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)

De sleutel is het gebruik van JSONPath om direct alleen de benodigde velden op te halen in plaats van handmatige verwerking.

Hier zijn enkele veelvoorkomende gebruiksscenario's:

  • API-scrapen – Gegevens extraheren uit REST API-reacties
  • JavaScript-sites – Query-objecten gebruikt door frontends
  • Mobile Apps – Parseer JSON-gegevens uit app-verkeer
  • Dynamische Content – Bouw datasets vanuit JavaScript aan de clientzijde

JSONPath maakt het schaalbaar schrapen van duizenden JSON-documenten mogelijk met eenvoudige padreeksen.

Parseren van grote JSON-bestanden

Hoewel JSONPath goed schaalbaar is, kan het parseren van enorme JSON-documenten nog steeds uitdagingen met zich meebrengen:

  • Geheugengebruik – Volledige JSON in het geheugen laden
  • CPU-belasting – Het parseren van complexe documenten is processorintensief
  • Netwerkoverdracht – Grote documenten betekenen meer bandbreedte

Enkele tips bij het werken met grote JSON-gegevens:

  • Gebruik streaming-parsers om te voorkomen dat JSON volledig wordt geladen
  • Compileer paden met parse() in plaats van opnieuw te parseren
  • Extraheer alleen de daadwerkelijk benodigde velden in plaats van volledige objecten
  • Te gebruiken laziness om onnodige objectscans te voorkomen
  • Draai op krachtige cloudservers bij het verwerken van TB+ schaalgegevens
  • Verdeel het parseren over clusters voor parallelle verwerking

In de meeste gevallen kan JSONPath op efficiënte wijze gegevens extraheren uit zelfs enorme JSON-bestanden met honderdduizenden records, mits op de juiste manier geoptimaliseerd.

Waarom ik graag JSONPath gebruik

Als ervaren proxy-engineer die veel met JSON-gegevens werkt, is dit de reden waarom ik JSONPath graag gebruik:

  • Beknopte syntaxis – Padexpressies zijn prachtig beknopt vergeleken met traditionele parseercode
  • Verhoogde Productiviteit – Dankzij de intuïtieve syntaxis kunt u JSON net zo eenvoudig bevragen als een database bevragen
  • Robuuste filtering – Dankzij de predikaatfilters is het selecteren van overeenkomende gegevens een fluitje van een cent
  • Razendsnelle prestaties – jsonpath-ng maakt gebruik van extreem geoptimaliseerde algoritmen onder de motorkap die bliksemsnelle data-extractie mogelijk maken, zelfs op grote datasets
  • Geheugen efficiënt – Omdat JSON selectief wordt geparseerd, is de geheugenvoetafdruk laag vergeleken met volledig parseren naar native objecten
  • Webscraping-kracht – Eenvoudige gegevensextractie uit API's en JavaScript-reacties is waar JSONPath uitblinkt

Hoewel tools als jq en grep geweldig zijn, vind ik JSONPath eenvoudiger en eleganter voor de meeste van mijn JSON-parseerbehoeften. De ondersteuning van het Python-ecosysteem met bibliotheken zoals jsonpath-ng maakt het mijn favoriete keuze voor het segmenteren en verdelen van JSON-gegevens.

JSONPath-ondersteuning in andere talen

Hoewel we ons op Python hebben geconcentreerd, is JSONPath beschikbaar in veel programmeertalen:

Omdat JSON een universeel gegevensformaat is, is het handig om er vanuit elke taal efficiënt query's op te kunnen uitvoeren. Gelukkig wordt JSONPath breed ondersteund.

Waarom JSONPath ertoe doet

JSON is snel essentieel geworden voor web-API's, microservices en front-end-applicaties. JSONPath brengt XPath-achtige querymogelijkheden naar de wereld van JSON-gegevens.

Het hebben van een gestandaardiseerde padtaal voor het eenvoudig extraheren van geneste JSON-waarden heeft veel voordelen:

  • Vereenvoudigt JSON-gegevensextractie op verschillende platforms en talen
  • Biedt een leesbaar alternatief voor lelijke regex-parsering
  • Maakt schaalbare webscraping mogelijk zonder dat volledige reacties hoeven te worden geparseerd
  • Maakt complexe transformaties mogelijk met behulp van projecties en filters
  • Ontgrendelt de mogelijkheid om op efficiënte wijze grote JSON-datasets op te vragen
  • Past op natuurlijke wijze in pijpleidingen naast andere JSON-tools zoals jq

Terwijl JSON zijn dominantie als het de facto formaat voor gegevensuitwisseling voortzet, zal het hebben van een reeks gemeenschappelijke JSONPath-operatoren helpen de complexiteit van het navigeren door grote JSON-documenten te temmen.

Conclusie

JSONPath biedt een elegante manier om waarden uit JSON-gegevens te extraheren en te transformeren via beknopte padexpressies.

Bibliotheken zoals jsonpath-ng maak de integratie van JSONPath in uw Python-projecten eenvoudig.

Sleutelfaciliteiten:

  • Met JSONPath kunt u eenvoudig query's uitvoeren op JSON-structuren met behulp van '.' en '[]'-operatoren
  • Filteren op eigenschapswaarden met behulp van predikaten schaalt goed
  • Transformaties kunnen worden toegepast met behulp van projecties en array-uitbreiding
  • JSONPath vermijdt de noodzaak om volledige JSON-objecten te parseren tijdens het scrapen
  • De syntaxis is gemodelleerd naar XPath-expressies voor het opvragen van XML
  • Ondersteund in veel programmeertalen

Voor het werken met op JSON gebaseerde webservices is JSONPath een onmisbare tool voor de toolkit van elke ontwikkelaar. Met JSONPath kunt u eenvoudige vragen stellen en precies de gegevens verkrijgen die u nodig heeft uit complexe JSON-documenten.

Doe mee aan het gesprek

Uw e-mailadres wordt niet gepubliceerd. Verplichte velden zijn gemarkeerd *