Passer au contenu

Introduction rapide à l'analyse de JSON avec JSONPath en Python

JSON est devenu de facto le standard d’échange de données sur le web. Les API, les services Web et les sites Web modernes utilisent largement JSON pour envoyer des données entre les serveurs et les clients.

Par exemple, selon BuiltWith, plus de 70 % des 10,000 XNUMX principaux sites Web utilisent les API JSON. Le format JSON est facile à générer et à analyser dans n'importe quel langage de programmation.

Cependant, extraire efficacement des informations significatives à partir de documents JSON volumineux peut encore s'avérer difficile. C'est là qu'intervient JSONPath : un langage de requête spécialisé pour simplifier la façon dont vous localisez et transformez les données JSON.

Le problème avec l'analyse JSON

Traditionnellement, les données JSON sont traitées dans les applications en les analysant entièrement dans des structures de données natives telles que les dicts Python. Vous analyserez l'intégralité de la réponse JSON même si vous n'avez besoin que d'un petit sous-ensemble de données.

Cette approche présente certains inconvénients :

  • Un ralentissement des performances – L’analyse de gros fichiers JSON en objets est coûteuse en calcul
  • Forte utilisation de la mémoire – L’intégralité de la structure JSON doit être conservée en mémoire
  • Code verbeux – Vous devez souvent écrire beaucoup de code de bouclage/traversement pour approfondir les objets analysés

Une alternative consiste à utiliser des expressions régulières pour extraire directement les fragments JSON correspondants. Cependant, les expressions régulières deviennent compliquées avec des structures imbriquées complexes. Il est également confronté à des noms de clés dynamiques ou à des profondeurs d'imbrication arbitraires.

JSONPath fournit un moyen plus propre et plus concis d'interroger JSON par rapport à l'analyse brute ou à la correspondance d'expressions régulières.

Présentation de JSONPath

Les expressions JSONPath décrivent comment accéder à des parties d'un document JSON. Il est conceptuellement similaire à XPath qui permet d'interroger des éléments et des attributs en XML :

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

Quelques avantages de l'approche JSONPath :

  • lisibilité – Les expressions de requête sont faciles à comprendre
  • Brièveté – Pas besoin de code de parcours détaillé
  • Flexibilité – Prend en charge les recherches, les filtres et les correspondances génériques
  • Performance – Algorithmes de matching très optimisés
  • Évolutivité – Peut traiter rapidement même des documents JSON volumineux

JSONPath fournit une alternative simple et évolutive pour extraire des données de JSON. Voyons ensuite comment cela fonctionne.

Interroger JSON avec JSONPath

Une expression JSONPath est une chaîne qui décrit comment localiser des valeurs dans une structure JSON. Par exemple:

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 utilise des opérateurs tels que :

  • . – Opérateur enfant
  • [] – Opérateur d'indice pour l'accès au tableau
  • * – Caractère générique pour tous les éléments correspondants
  • ?() – Filtrage des prédicats

Les enchaîner ensemble permet d'interroger efficacement des JSON complexes :

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

Fini le code en boucle profondément imbriqué ! JSONPath correspond directement aux objets sans avoir besoin d'analyser entièrement l'intégralité de l'arborescence JSON.

Opérateurs JSONPath disponibles

Voici un résumé des opérateurs disponibles dans JSONPath :

Opérateurs de chemin

  • $ – Objet racine
  • @ – Objet actuel
  • . or [] – Opérateur enfant
  • .. – Rechercher des descendants de manière récursive

Opérateurs de filtrage

  • [?(<expression>)]– Filtrer les objets
  • [(<condition>)]– Filtre basé sur la condition

Opérateurs de tableau

  • * – Wildcard indexe tous les éléments
  • [<index>] – Position de l'indice
  • [start:end] – Tranche de tableau
  • [?(<condition>)] – Filtrer

Opérateurs de projection

  • [] – Projection – Extrait les propriétés répertoriées
  • [@] – Projection d'index – Aplatit les tableaux

Autres opérateurs

  • | – Opérateur syndical
  • () – Opérateur prioritaire
  • , – Délimite plusieurs résultats

Ceux-ci vous offrent une grande flexibilité pour interroger, filtrer et transformer les données JSON à l'aide de chaînes de chemin simples.

JSONPath contre XPath pour XML

Étant donné que JSONPath partage de nombreuses similitudes avec XPath, il vaut la peine de comparer les deux :

XPath

  • Langage de requête pour XML
  • Permet de parcourir l'arborescence XML
  • Prend en charge les axes avancés comme //, /*, //@
  • Utiliser pour extraire les nœuds XML

Chemin JSON

  • Langage de requête équivalent pour JSON
  • Syntaxe inspirée de XPath
  • Syntaxe plus simple car JSON est plus simple sur le plan de la représentation que XML
  • Implémentation rapide car aucune analyse XML n'est nécessaire

Les deux permettent de sélectionner des nœuds dans des structures de données hiérarchiques. JSONPath pourrait être considéré comme une version simplifiée de XPath spécialisée pour JSON plutôt que XML.

JSONPath a été implémenté pour de nombreux langages de programmation. Certaines bibliothèques populaires pour Python sont :

BibliothèqueDescription
jsonpath-ngBibliothèque recommandée, rapide avec des fonctionnalités avancées
jsonpath-rwImplémentation de référence conforme
jsonpathImplémentation simple mais fonctionnalités limitées

Pour la plupart des utilisations, jsonpath-ng offre la meilleure combinaison de conformité, de fonctionnalités et de performances.

Voyons comment l'utiliser plus en détail.

Requête et filtrage avec jsonpath-ng

Tout d'abord, installez jsonpath-ng :

pip install jsonpath-ng

Importer:

from jsonpath_ng import jsonpath, parse

Quelques exemples:

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

Vous pouvez également utiliser la parse() méthode qui compile le chemin pour de meilleures performances :

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

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

Cela fonctionne plus rapidement lorsque vous appliquez le même chemin à plusieurs documents JSON.

Filtrage des données JSON

L'une des fonctionnalités les plus puissantes de JSONPath est sa syntaxe de filtrage.

Les filtres permettent de sélectionner des objets correspondant à des critères spécifiques. Par exemple:

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

Cela donne des voitures plus récentes que 2015.

Vous pouvez filtrer à l'aide de comparaisons telles que :

  • Mathématique: =, !=, >, <=, etc.
  • Logique: and, or, not
  • Expressions régulières: =~, !=~
  • Existence: exists(), ?()

Les filtres peuvent également être combinés :

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

Cela permet de fabriquer des voitures électriques après 2010.

Transformer les données JSON

Outre l'extraction de données, JSONPath peut transformer des objets JSON à l'aide d'opérateurs tels que :

  • [] – Projection pour remodeler les objets
  • [@] – Indexation des tableaux pour aplatir

Par exemple, aplatir les données d'une voiture en une simple liste :

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

La @ fait une projection basée sur un index.

Le chaînage du filtre, des projections et des tranches permet de restructurer JSON par programmation.

Fonctionnalités avancées de jsonpath-ng

Quelques fonctionnalités avancées supplémentaires fournies par jsonpath-ng :

Fonctions personnalisées

Vous pouvez enregistrer des fonctions personnalisées pour étendre JSONPath :

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

jsonpath.register_custom_function(format_price, ‘format‘)

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

Cela permet d'implémenter des transformations de données complexes directement dans les expressions JSONPath.

Mise en cache et optimisation

jsonpath-ng compile et optimise les requêtes pour les performances. Il prend également en charge :

  • Mise en cache pour la vitesse
  • Correspondance paresseuse pour éviter les analyses inutiles
  • Optimisation du rendement

Il fonctionne donc bien même avec d'énormes documents JSON.

Opérateurs supplémentaires

Quelques autres opérateurs utiles :

  • ?() – Contrôle d’existence
  • =~, !=~ – Correspondance d’expression régulière
  • in – Contient un chèque
  • all – Quantificateur universel

Méthodes JSONPath

Méthodes d'assistance telles que :

  • find() – Renvoie les correspondances
  • parse() – Chemin des compilations

Fournissez une API plus simple pour les requêtes courantes.

Utiliser JSONPath pour le Web Scraping

L'une des applications les plus utiles de JSONPath consiste à extraire des données lors du scraping Web.

Les sites Web modernes s'appuient fortement sur JSON pour transmettre des données :

  • Apis – JSON est le format standard des API REST
  • Données asynchrones – JSON est utilisé avec JavaScript pour les mises à jour dynamiques des pages
  • Métadonnées de la page – Données du site souvent stockées dans des scripts au format JSON

Analyser manuellement tout ce JSON serait fastidieux. JSONPath permet d'interroger facilement uniquement les fragments dont vous avez besoin.

Par exemple, voici comment extraire les données produit d’une page de commerce électronique :

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)

La clé consiste à utiliser JSONPath pour récupérer directement uniquement les champs nécessaires au lieu d'un traitement manuel.

Voici quelques cas d’utilisation courants :

  • Grattage d'API – Extraire les données des réponses de l’API REST
  • Sites Javascript – Objets de requête utilisés par les frontends
  • Application mobile – Analyser les données JSON du trafic des applications
  • Contenu dynamique – Créer des ensembles de données à partir de JavaScript côté client

JSONPath permet de récupérer de manière évolutive des milliers de documents JSON avec des chaînes de chemin simples.

Analyse de gros fichiers JSON

Bien que JSONPath s'adapte bien, l'analyse de documents JSON volumineux peut toujours présenter des défis :

  • Utilisation de la mémoire – Chargement du JSON complet en mémoire
  • Charge du processeur – L’analyse de documents complexes nécessite beaucoup de ressources processeur
  • Transfert réseau – Les documents volumineux signifient plus de bande passante

Quelques conseils lorsque vous travaillez avec des données JSON volumineuses :

  • Utilisez des analyseurs de streaming pour éviter de charger complètement JSON
  • Compiler les chemins avec parse() au lieu de ré-analyser
  • Extrayez uniquement les champs réellement nécessaires au lieu des objets complets
  • Utilisez laziness pour éviter les analyses d'objets inutiles
  • Exécutez sur des serveurs cloud puissants lors de la gestion des données à l'échelle TB+
  • Répartir l'analyse sur les clusters pour un traitement parallèle

Dans la plupart des cas, JSONPath peut extraire efficacement des données, même à partir de fichiers JSON volumineux contenant des centaines de milliers d'enregistrements, lorsqu'il est correctement optimisé.

Pourquoi j'aime utiliser JSONPath

En tant qu'ingénieur proxy expérimenté qui travaille beaucoup avec les données JSON, voici pourquoi j'aime utiliser JSONPath :

  • Syntaxe concise – Les expressions de chemin sont magnifiquement succinctes par rapport au code d'analyse traditionnel
  • Productivité accrue – Vous pouvez interroger JSON aussi facilement que interroger une base de données grâce à la syntaxe intuitive
  • Filtrage robuste – Les filtres de prédicats facilitent la sélection des données correspondantes
  • Des performances ultra-rapides – jsonpath-ng utilise des algorithmes extrêmement optimisés sous le capot qui permettent une extraction de données ultra-rapide, même sur de grands ensembles de données
  • Mémoire efficace – Puisqu'il analyse JSON de manière sélective, l'empreinte mémoire est faible par rapport à une analyse complète des objets natifs
  • Puissance de grattage Web – L'extraction facile des données à partir des API et des réponses JavaScript est là où JSONPath brille

Bien que des outils comme jq et grep soient excellents, je trouve que JSONPath est plus simple et plus élégant pour la plupart de mes besoins d'analyse JSON. La prise en charge de l'écosystème Python avec des bibliothèques comme jsonpath-ng en fait mon choix privilégié pour découper et découper les données JSON.

Prise en charge de JSONPath dans d'autres langues

Bien que nous nous soyons concentrés sur Python, JSONPath est disponible dans de nombreux langages de programmation :

Étant donné que JSON est un format de données universel, il est utile de pouvoir l'interroger efficacement à partir de n'importe quel langage. Heureusement, JSONPath est largement pris en charge.

Pourquoi JSONPath est important

JSON est rapidement devenu essentiel pour les API Web, les microservices et les applications frontales. JSONPath apporte des capacités d'interrogation de type XPath au monde des données JSON.

Disposer d'un langage de chemin standardisé pour extraire facilement les valeurs JSON imbriquées présente de nombreux avantages :

  • Simplifie l'extraction de données JSON sur toutes les plates-formes et langages
  • Fournit une alternative lisible à l'analyse laide des regex
  • Permet un scraping Web évolutif sans avoir besoin d'analyser des réponses entières
  • Permet des transformations complexes à l'aide de projections et de filtres
  • Permet d'interroger efficacement d'énormes ensembles de données JSON
  • S'intègre naturellement dans les pipelines aux côtés d'autres outils JSON comme jq

Alors que JSON continue de dominer en tant que format d'échange de données de facto, disposer d'un ensemble d'opérateurs JSONPath communs aidera à maîtriser la complexité de la navigation dans les documents JSON volumineux.

Conclusion

JSONPath fournit un moyen élégant d'extraire et de transformer les valeurs des données JSON via des expressions de chemin concises.

Les bibliothèques aiment jsonpath-ng simplifiez l'intégration de JSONPath dans vos projets Python.

Principales sorties:

  • JSONPath permet d'interroger facilement les structures JSON à l'aide de '.' et les opérateurs '[]'
  • Le filtrage par valeurs de propriété à l'aide de prédicats s'adapte bien
  • Les transformations peuvent être appliquées à l'aide de projections et d'expansion de tableau
  • JSONPath évite d'avoir à analyser des objets JSON entiers lors du scraping
  • La syntaxe est calquée sur les expressions XPath pour interroger XML
  • Pris en charge dans de nombreux langages de programmation

Pour travailler avec des services Web basés sur JSON, JSONPath est un outil indispensable pour la boîte à outils de tout développeur. JSONPath vous permet de poser des questions simples et d'obtenir uniquement les données dont vous avez besoin à partir de documents JSON complexes.

Prendre part à la conversation

Votre adresse email n'apparaitra pas. Les champs obligatoires sont marqués *