Ir al contenido

Introducción rápida al análisis de JSON con JSONPath en Python

JSON se ha convertido en el estándar de facto para el intercambio de datos en la web. Las API, los servicios web y los sitios web modernos utilizan ampliamente JSON para enviar datos entre servidores y clientes.

Por ejemplo, según BuiltWith, más del 70% de los 10,000 sitios web principales utilizan API JSON. El formato JSON es fácil de generar y analizar en cualquier lenguaje de programación.

Sin embargo, extraer de manera eficiente información significativa de documentos JSON de gran tamaño aún puede resultar un desafío. Aquí es donde entra en juego JSONPath: un lenguaje de consulta especializado para simplificar la forma de localizar y transformar datos JSON.

El problema con el análisis de JSON

Tradicionalmente, los datos JSON se procesan en aplicaciones analizándolos completamente en estructuras de datos nativas como los dictados de Python. Analizaría la respuesta JSON completa incluso si solo necesitara un pequeño subconjunto de datos.

Este enfoque tiene algunas desventajas:

  • Rendimiento lento – Analizar archivos JSON grandes en objetos es computacionalmente costoso
  • Alto uso de memoria – Toda la estructura JSON debe mantenerse en la memoria.
  • código detallado – A menudo tienes que escribir una gran cantidad de código de bucle/recorrido para profundizar en los objetos analizados.

Una alternativa es utilizar expresiones regulares para extraer directamente fragmentos JSON coincidentes. Sin embargo, las expresiones regulares se vuelven complicadas con estructuras anidadas complejas. También tiene problemas con nombres de claves dinámicos o profundidades de anidamiento arbitrarias.

JSONPath proporciona una forma más limpia y concisa de consultar JSON en comparación con el análisis sin formato o la coincidencia de expresiones regulares.

Presentamos JSONPath

Las expresiones JSONPath describen cómo acceder a partes de un documento JSON. Es conceptualmente similar a XPath que permite consultar elementos y atributos en XML:

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

Algunas ventajas del enfoque JSONPath:

  • legibilidad – Las expresiones de consulta son fáciles de entender.
  • Brevedad – No es necesario un código transversal detallado
  • Flexibilidad – Admite búsquedas, filtros y coincidencias con comodines
  • Rendimiento – Algoritmos de coincidencia muy optimizados
  • Escalabilidad – Puede procesar rápidamente incluso documentos JSON de gran tamaño

JSONPath proporciona una alternativa sencilla y escalable para extraer datos de JSON. A continuación repasemos cómo funciona.

Consultando JSON con JSONPath

Una expresión JSONPath es una cadena que describe cómo ubicar valores dentro de una estructura JSON. Por ejemplo:

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 utiliza operadores como:

  • . – Niño operador
  • [] – Operador de subíndice para acceso a matriz
  • * – Comodín para todos los elementos coincidentes
  • ?() – Filtrado de predicados

Encadenarlos permite realizar consultas eficientes en JSON complejos:

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

¡No más código de bucle anidado profundo! JSONPath busca objetos directamente sin necesidad de analizar completamente todo el árbol JSON.

Operadores JSONPath disponibles

A continuación se muestra un resumen de los operadores disponibles en JSONPath:

Operadores de ruta

  • $ – Objeto raíz
  • @ - Objeto actual
  • . or [] – Niño operador
  • .. – Buscar descendientes recursivamente

Operadores de filtro

  • [?(<expression>)]– Filtrar objetos
  • [(<condition>)]– Filtrar según la condición

Operadores de matrices

  • * – El comodín indexa todos los elementos.
  • [<index>] – Posición del índice
  • [start:end] – Rebanada de matriz
  • [?(<condition>)] - filtro

Operadores para Proyección

  • [] – Proyección – Extrae las propiedades enumeradas
  • [@] – Proyección de índice – Aplana matrices

Otros operadores

  • | – Operador de la Unión
  • () – Operador prioritario
  • , – Delimita múltiples resultados

Estos le brindan una amplia flexibilidad para consultar, filtrar y transformar datos JSON utilizando cadenas de ruta simples.

JSONPath frente a XPath para XML

Dado que JSONPath comparte muchas similitudes con XPath, vale la pena compararlos:

XPath

  • Lenguaje de consulta para XML
  • Permite recorrer el árbol XML.
  • Admite ejes avanzados como //, /*, //@
  • Úselo para extraer nodos XML

Ruta JSON

  • Lenguaje de consulta equivalente para JSON
  • Sintaxis inspirada en XPath
  • Sintaxis más simple ya que JSON es representativamente más simple que XML
  • Implementación rápida ya que no se necesita análisis XML

Ambos permiten seleccionar nodos en estructuras de datos jerárquicas. JSONPath podría considerarse una versión simplificada de XPath especializada para JSON en lugar de XML.

JSONPath se ha implementado para muchos lenguajes de programación. Algunas bibliotecas populares para Python son:

BibliotecaDescripción
jsonpath-ngBiblioteca recomendada, rápida y con funciones avanzadas.
jsonpath-rwImplementación de referencia compatible
ruta jsonImplementación simple pero características limitadas

Para la mayoría de los usos, jsonpath-ng proporciona la mejor combinación de cumplimiento, características y rendimiento.

Veamos cómo usarlo con más detalle.

Consulta y filtrado con jsonpath-ng

Primero, instale jsonpath-ng:

pip install jsonpath-ng

Importar:

from jsonpath_ng import jsonpath, parse

Algunos ejemplos:

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

También puedes utilizar la parse() método que compila la ruta para un mejor rendimiento:

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

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

Esto funciona más rápido cuando se aplica la misma ruta a varios documentos JSON.

Filtrado de datos JSON

Una de las características más poderosas de JSONPath es su sintaxis de filtrado.

Los filtros permiten seleccionar objetos que coincidan con criterios específicos. Por ejemplo:

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

Esto hace que los autos sean más nuevos que 2015.

Puedes filtrar usando comparaciones como:

  • Matemático: =, !=, >, <=, etc.
  • Lógico: and, or, not
  • Expresiones regulares: =~, !=~
  • Existencia: exists(), ?()

Los filtros también se pueden combinar:

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

Se trata de coches eléctricos fabricados después de 2010.

Transformar datos JSON

Además de extraer datos, JSONPath puede transformar objetos JSON utilizando operadores como:

  • [] – Proyección para remodelar objetos.
  • [@] – Indexación de matrices para aplanar

Por ejemplo, reducir los datos del automóvil a una lista simple:

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

La @ hace una proyección basada en índices.

El encadenamiento de filtros, proyecciones y cortes permite reestructurar JSON mediante programación.

Funciones avanzadas de jsonpath-ng

Algunas funciones avanzadas adicionales proporcionadas por jsonpath-ng:

Funciones personalizadas

Puede registrar funciones personalizadas para ampliar JSONPath:

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

jsonpath.register_custom_function(format_price, ‘format‘)

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

Esto permite implementar transformaciones de datos complejas directamente dentro de expresiones JSONPath.

Almacenamiento en caché y optimización

jsonpath-ng compila y optimiza consultas para mejorar el rendimiento. También soporta:

  • Almacenamiento en caché para velocidad
  • Coincidencia diferida para evitar escaneos innecesarios
  • Optimización del rendimiento de salida

Por lo tanto, funciona bien incluso con documentos JSON enormes.

Operadores adicionales

Algunos otros operadores útiles:

  • ?() – Verificación de existencia
  • =~, !=~ – Coincidencia de expresiones regulares
  • in – Contiene cheque
  • all – Cuantificador universal

Métodos JSONPath

Métodos auxiliares como:

  • find() – Devuelve partidos
  • parse() – Compila la ruta

Proporcione una API más simple para consultas comunes.

Usando JSONPath para Web Scraping

Una de las aplicaciones más útiles de JSONPath es la extracción de datos durante el web scraping.

Los sitios web modernos dependen en gran medida de JSON para transmitir datos:

  • API – JSON es el formato estándar para las API REST
  • Datos asíncronos – JSON se utiliza con JavaScript para actualizaciones dinámicas de páginas.
  • Metadatos de página – Los datos del sitio a menudo se almacenan en scripts como JSON

Analizar manualmente todo este JSON sería engorroso. JSONPath permite consultar fácilmente sólo los fragmentos que necesita.

Por ejemplo, aquí se explica cómo extraer datos de productos de una página de comercio electrónico:

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 clave es usar JSONPath para capturar directamente solo los campos necesarios en lugar del procesamiento manual.

A continuación se muestran algunos casos de uso comunes:

  • Raspado de API – Extraer datos de las respuestas de la API REST
  • Sitios JavaScript – Consultar objetos utilizados por frontends.
  • Localización de – Analizar datos JSON del tráfico de aplicaciones.
  • Contenido dinámico – Construir conjuntos de datos desde JavaScript del lado del cliente

JSONPath permite extraer de forma escalable miles de documentos JSON con cadenas de ruta simples.

Análisis de archivos JSON grandes

Si bien JSONPath se escala bien, el análisis de documentos JSON de gran tamaño aún puede presentar desafíos:

  • Uso de memoria – Cargando JSON completo en la memoria
  • Carga de la CPU – El análisis de documentos complejos requiere un uso intensivo del procesador.
  • transferencia de red – Los documentos grandes significan más ancho de banda

Algunos consejos al trabajar con datos JSON de gran tamaño:

  • Utilice analizadores de transmisión para evitar cargar JSON por completo
  • Compilar rutas con parse() en lugar de volver a analizar
  • Extraiga solo los campos reales necesarios en lugar de objetos completos
  • Uso laziness para evitar escaneos de objetos innecesarios
  • Ejecute en potentes servidores en la nube cuando maneje datos de escala TB+
  • Distribuya el análisis entre clústeres para el procesamiento paralelo

En la mayoría de los casos, JSONPath puede extraer datos de manera eficiente incluso desde archivos JSON enormes con cientos de miles de registros cuando se optimiza adecuadamente.

Por qué me encanta usar JSONPath

Como ingeniero de proxy experimentado que trabaja extensamente con datos JSON, he aquí por qué me encanta usar JSONPath:

  • Sintaxis concisa – Las expresiones de ruta son maravillosamente concisas en comparación con el código de análisis tradicional.
  • Productividad incrementada – Puede consultar JSON tan fácilmente como consultar una base de datos gracias a la sintaxis intuitiva
  • Filtrado robusto – Los filtros de predicados facilitan la selección de datos coincidentes.
  • Rendimiento ultrarrápido – jsonpath-ng utiliza algoritmos extremadamente optimizados que permiten una extracción de datos ultrarrápida incluso en grandes conjuntos de datos
  • Memoria eficiente – Dado que analiza JSON de forma selectiva, el uso de memoria es bajo en comparación con el análisis completo de objetos nativos.
  • Poder de raspado web – La fácil extracción de datos de API y respuestas de JavaScript es donde brilla JSONPath

Si bien herramientas como jq y grep son excelentes, encuentro que JSONPath es más simple y elegante para la mayoría de mis necesidades de análisis de JSON. El soporte del ecosistema Python con bibliotecas como jsonpath-ng lo convierte en mi opción preferida para dividir y dividir datos JSON.

Soporte JSONPath en otros idiomas

Si bien nos hemos centrado en Python, JSONPath está disponible en muchos lenguajes de programación:

Dado que JSON es un formato de datos universal, es útil poder consultarlo de manera eficiente desde cualquier idioma. Afortunadamente, JSONPath cuenta con un amplio soporte.

Por qué es importante JSONPath

JSON se ha vuelto rápidamente esencial para las API web, los microservicios y las aplicaciones front-end. JSONPath aporta capacidades de consulta similares a XPath al mundo de los datos JSON.

Tener un lenguaje de ruta estandarizado para extraer fácilmente valores JSON anidados tiene muchos beneficios:

  • Simplifica la extracción de datos JSON entre plataformas e idiomas.
  • Proporciona una alternativa legible al feo análisis de expresiones regulares
  • Permite el web scraping escalable sin necesidad de analizar respuestas completas
  • Permite transformaciones complejas mediante proyecciones y filtros.
  • Desbloquea la capacidad de consultar de manera eficiente enormes conjuntos de datos JSON
  • Se adapta naturalmente a tuberías junto con otras herramientas JSON como jq

A medida que JSON continúa dominando como formato de intercambio de datos de facto, tener un conjunto de operadores JSONPath comunes ayudará a controlar la complejidad de navegar por documentos JSON de gran tamaño.

Conclusión

JSONPath proporciona una forma elegante de extraer y transformar valores de datos JSON mediante expresiones de ruta concisas.

Bibliotecas como jsonpath-ng Simplifique la integración de JSONPath en sus proyectos de Python.

Puntos clave:

  • JSONPath permite consultar fácilmente estructuras JSON usando '.' y operadores '[]'
  • El filtrado por valores de propiedad utilizando predicados escala bien
  • Las transformaciones se pueden aplicar mediante proyecciones y expansión de matrices.
  • JSONPath evita la necesidad de analizar objetos JSON completos al realizar scraping
  • La sintaxis se modela a partir de expresiones XPath para consultar XML.
  • Compatible con muchos lenguajes de programación

Para trabajar con servicios web basados ​​en JSON, JSONPath es una herramienta indispensable para el conjunto de herramientas de cualquier desarrollador. JSONPath le permite hacer preguntas sencillas y obtener solo los datos que necesita de documentos JSON complejos.

Únase a la conversación

Su dirección de correo electrónico no será publicada. Las areas obligatorias están marcadas como requeridas *