Meteen naar de inhoud

JSON parseren met Python als een professional

Hallo vriend! JSON is tegenwoordig overal. Of je nu webservices bouwt, gegevens verzamelt of met API's communiceert, de kans is groot dat je op een gegeven moment JSON in Python moet parseren.

Uit mijn meer dan vijf jaar ervaring heb ik ontdekt dat Python geweldige tools heeft voor het omgaan met JSON. Daarom wilde ik enkele professionele tips en codefragmenten delen waarmee u JSON-gegevens als een baas kunt parseren, manipuleren en analyseren!

Opfrisser voor JSON-indeling

Laten we beginnen met een snelle opfriscursus over de JSON-syntaxis en -structuur.

JSON staat voor JavaScript Object Notation. Het is uitgegroeid tot de universele standaard voor het serialiseren en verzenden van gegevens via internet.

Think Statistawerkt ruim 70% van de ontwikkelaars regelmatig met JSON API’s.

JSON vertegenwoordigt gegevens als sleutel/waarde-paren:

{
  "name": "John",
  "age": 30,
  "address": {
    "street": "123 Main St",
    "city": "San Francisco" 
  }
}

Het bestaat uit:

  • Objecten – Ongeordende verzamelingen sleutel/waarde-paren aangegeven met { }
  • arrays – Bestelde collecties aangegeven met [ ]
  • sleutel – Altijd een touwtje
  • Waarde – Kan een tekenreeks, getal, booleaanse waarde, null, object of array zijn

Deze eenvoudige syntaxis maakt JSON gemakkelijk te lezen en te parseren, zowel voor mensen als machines.

Laten we nu eens kijken naar technieken voor het parseren van JSON in Python!

JSON-tekenreeksen parseren

De meest voorkomende JSON-parseertaak is het nemen van een onbewerkte JSON-tekenreeks en deze omzetten in een Python-dictaat.

Python is ingebouwd json module biedt eenvoudige methoden om dit aan te pakken:

json.loads() – Parseert een JSON-tekenreeks en retourneert een Python-object

import json

json_str = ‘{"name": "John", "age": 30}‘
data = json.loads(json_str)

print(data[‘name‘]) # John

json.dumps() – Serialiseert een Python-object in een JSON-tekenreeks

data = {
  ‘name‘: ‘John‘,
  ‘age‘: 30
}

json_str = json.dumps(data) 

print(json_str) 
# {"name": "John", "age": 30}

De json.loads() methode parseert JSON en converteert deze naar native Python-datastructuren. Het maakt moeiteloze serialisatie mogelijk van string naar dict, list, str, int etc.

Het zal echter een json.decoder.JSONDecodeError als de JSON ongeldig is. Zorg er dus voor dat u het in try/except verpakt.

De json.dumps() methode doet het omgekeerde en codeert Python-objecten als JSON-strings. Dit is handig voor het uitvoeren van gegevens of het verzenden ervan naar andere systemen.

JSON-bestanden lezen en parseren

Naast snaren kunnen we ook de json module om JSON-bestanden te laden en te parseren.

Dit JSON-bestand data.json bevat werknemersgegevens:

{
  "employees": [
    { "name": "John", "email": "[email protected]"},
    { "name": "Jane", "email": "[email protected]"}
  ]
}

Om het in Python te laden en te parseren:

import json

with open(‘data.json‘) as f:
  data = json.load(f)

for employee in data[‘employees‘]:
  print(employee[‘name‘]) 
# John 
# Jane

We openen het bestand en geven het door json.load()en haal een Python-object terug dat de geparseerde JSON bevat.

In dit geval is het een woordenboek met een employees sleutel die een lijst met werknemersobjecten bevat.

Het belangrijkste is json.load() heeft het bestand gelezen, de JSON geparseerd en ons native Python-objecten gegeven waar we meteen mee kunnen werken!

Mooie afdrukken JSON

Hier is een handige truc voor het debuggen: JSON op een leesbare manier formatteren met behulp van Python json.dumps() methode.

Geef de indent parameter om deze op te maken met nieuwe regels en spaties:

data = {
  ‘name‘: ‘John‘,
  ‘age‘: 30,
  ‘address‘: {
    ‘street‘: ‘123 Main St‘,
    ‘city‘: ‘San Francisco‘
  }
}

print(json.dumps(data, indent=4))

Output:

{
    "name": "John",
    "age": 30,
    "address": {
        "street": "123 Main St",
        "city": "San Francisco"
    }
}

De indent regelt het aantal spaties. Hierdoor wordt het afgedrukt met een mooie opmaak, zodat het gemakkelijker visueel te ontleden is.

Beveel het gebruik ten zeerste aan json.dumps(indent=4) telkens wanneer JSON in de terminal wordt afgedrukt voor een betere zichtbaarheid.

Geneste JSON-objecten parseren

JSON in de echte wereld heeft vaak geneste objecten en arrays. Dit kan lastig zijn om te ruziën in Python.

Gelukkig bieden Panda's een geweldig hulpprogramma genaamd json_normalize() dat geneste JSON plat maakt tot een platte tabel:

from pandas.io.json import json_normalize

data = {
  "cars": [
    {"make": "Ford", "models": ["Fiesta", "Focus", "Mustang"]},
    {"make": "BMW", "models": ["320", "X3", "X5"]},
    {"make": "Fiat", "models": ["500", "Panda"]}
  ]
}

df = json_normalize(data, ‘cars‘, [‘make‘, ‘models‘])

print(df)

Output:

makenmodellen
0doorwaadbare plaatsdansfeestje
1doorwaadbare plaatsFocus
2doorwaadbare plaatsMustang
3BMW320
4BMWX3
5BMWX5
6Fiat500
7FiatPanda

Het maakt de geneste 'auto's'-array plat in rijen, terwijl de kolommen merk en model behouden blijven.

Dit is enorm waardevol wanneer u geneste JSON-gegevens in panda's moet analyseren!

JSON naar CSV converteren

Voor analyse in Excel, Tableau of andere tools wilt u wellicht JSON naar CSV-indeling exporteren.

Geen probleem, de panda's DataFrame.to_csv() methode maakt dit een fluitje van een cent:

df = json_normalize(data) 

df.to_csv(‘data.csv‘, index=False)

Door te passeren index=False de panda-indexkolom wordt weggelaten.

U kunt ook JSON-gegevens toevoegen aan een bestaande CSV:

df.to_csv(‘data.csv‘, mode=‘a‘, header=False, index=False)

Dit biedt een schone manier om JSON -> CSV te extraheren voor downstream-gebruik.

Omgaan met duplicaten

In tegenstelling tot Python-woordenboeken staat JSON technisch dubbele sleutels toe, zoals:

{
  "name": "John",
  "age": 30,
  "name": "Jane"
}

Dit zal een TypeError in json.loads() aangezien Python-dictaten unieke sleutels vereisen.

Als u duplicaten wilt verwerken, geeft u de object_pairs_hook parameter:

from collections import defaultdict

def handle_dups(pairs):
  d = defaultdict(list)
  for k, v in pairs:
    d[k].append(v)

  return dict(d)

data = json.loads(json_str, object_pairs_hook=handle_dups) 

Hiermee worden waarden van dubbele sleutels verzameld in lijsten:

{
  "name": ["John","Jane"],
  "age": 30
} 

Een alternatief is dat latere duplicaten eerdere duplicaten kunnen overschrijven:

def handle_dups(d):
  return {k: v for k, v in d.items()}

data = json.loads(json_str, object_hook=handle_dups)

So object_pairs_hook geeft u opties voor het verwerken van JSON-objecten met dubbele sleutels.

JSON-datums parseren

Omgaan met datums is rommelig. JSON vertegenwoordigt datums als tekenreeksen:

{
  "date": "2019-01-01" 
}

Standaard json.loads() zal dit parseren in een str.

We kunnen gebruik maken object_hook datums automatisch converteren:

from datetime import datetime

def parse_dates(data):
  for k, v in data.items():
    if isinstance(v, str):
        try:
            data[k] = datetime.strptime(v, "%Y-%m-%d") 
        except ValueError:
            pass

  return data

data = json.loads(json_str, object_hook=parse_dates)
print(data[‘date‘].year) # 2019

Nu worden datumreeksen geparseerd datetime objecten automatisch!

Incrementele JSON-parsering

Het parseren van grote JSON-bestanden kan het geheugen uitputten. De json module heeft streaming-parser JSONDecoder om dit af te handelen:

import json

with open(‘big.json‘) as f:
  parser = json.JSONDecoder()
  for obj in parser.decode(f.read()): 
    print(obj)

Het ontleedt stapsgewijs de JSON en levert gaandeweg Python-objecten op.

Voor JSON-arrays kunt u ook slagen chunk_size naar json.load():

with open(‘big.json‘) as f:
  for obj in json.load(f, chunk_size=1000):
    print(obj)

Het laadt de JSON-array in stukjes van 1000 elementen. Ideaal voor grote datasets!

JSON-schema's valideren

Bij het accepteren van JSON-gegevens helpt validatie problemen vroegtijdig op te sporen.

De jsonschema Met de module kunt u een schema definiëren en gegevens op basis daarvan valideren:

from jsonschema import validate

schema = {
  "type": "object",
  "required": ["name", "email"],
  "properties": {
    "name": {"type": "string"},
    "email": {"type": "string"} 
  }
}

data = {"name": "John"}

try:
  validate(data, schema)
except Exception as e:
  print(e) # ‘email‘ is a required property

Hiermee wordt gecontroleerd op verplichte velden, verwachte typen, enzovoort. Cruciaal voor robuuste JSON API's.

Welke parser moet ik gebruiken?

Python heeft een paar opties voor het parseren van JSON:

  • json – De standaardbibliotheek JSON-module. Geweldige balans tussen snelheid, compatibiliteit en opties.
  • eenvoudige json – Externe module gericht op prestatie. Tot 10x sneller dan json.
  • panda's – pd.read_json() en json_normalize() blinken uit in het omzetten van JSON in DataFrames.

Mijn aanbeveling:

  • json – Beste voor algemene parseertaken zoals het lezen van bestanden of het eenvoudig parseren van tekenreeksen.
  • panda's – Als JSON → DataFrame uw einddoel is, zijn panda's niet te verslaan.
  • eenvoudige json – Voor prestatiekritische applicaties die met veel JSON te maken hebben.

Kortom, Python maakt het parseren van JSON een plezier, of het nu gaat om eenvoudige tekenreeksen of enorme datasets. De json en pandas modules bieden alle tools die u nodig heeft.

Ik hoop dat deze tips je helpen een JSON-parsing-ninja te worden! Laat het me weten als je nog vragen hebt.

Doe mee aan het gesprek

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