Volver al blog

JMESPath Web Scraping: Consulta APIs JSON de manera declarativa

Emily Chen
Emily Chen

Advanced Data Extraction Specialist

23-Jul-2026

Resumen:

  • jmespath consulta JSON de forma declarativa. Una expresión transforma una respuesta de API anidada en registros planos: sin bucles, sin caminar manualmente por diccionarios.
  • Las API JSON son el objetivo de raspado más limpio. Muchos sitios construyen sus páginas a partir de un punto final JSON en el backend; obtiene ese JSON y los datos llegan ya estructurados.
  • Lo que jmespath no hace es obtener. No tiene cliente HTTP y no analiza HTML; tú le entregas un objeto JSON decodificado y él lo consulta.
  • Obtén a través de Scrapeless cuando la API está protegida. Una ejecución en vivo obtuvo una API de productos a través de la API Universal de Raspado de Scrapeless, luego usó jmespath para seleccionar, filtrar y ordenar los resultados.
  • Filtros y proyecciones en una línea. products[?price < \50`].titledevolvió los seis productos por debajo de $50;sort_by(products, &price)[0]` devolvió el más barato.
  • Gratis para comenzar del lado de la obtención. Crea tu clave API de Scrapeless en app.scrapeless.com.

Lo que jmespath es y lo que no es

jmespath es un lenguaje de consulta para JSON. Escribes una expresión que describe la forma que deseas, y la biblioteca recorre el documento y la devuelve: las proyecciones extraen un campo de cada elemento de una lista, los filtros mantienen solo los elementos que cumplen una condición, y los hash de multiselección reconstruyen cada elemento en un registro más pequeño. Es el mismo lenguaje de expresión que utiliza la CLI de AWS para su bandera --query, estandarizado por la especificación JMESPath, y disponible como una pequeña biblioteca de Python.

Es un lenguaje de consulta, no un raspador. jmespath no tiene cliente HTTP, no obtiene URL y no analiza HTML; opera sobre un valor JSON que ya has decodificado, definido por el estándar de intercambio de datos JSON. Así que una configuración de "raspado web jmespath" tiene dos capas: algo que devuelve el JSON, y jmespath que lo transforma. Esto es importante porque una gran parte de los datos en sitios modernos se proporciona a partir de una API JSON de backend que la página llama en segundo plano; acceder directamente a ese punto final omite por completo el análisis HTML. Cuando el punto final está restringido geográficamente o limitado por tasa, esta guía lo obtiene a través de la API Universal de Raspado de Scrapeless. Para el lado HTML del raspado, el tutorial de raspado web de Python cubre selectores en su lugar.

Instalación

jmespath y requests son toda la cadena de herramientas. La versión contra la que se escribió esta guía es jmespath 1.0.1:

bash Copy
pip install "jmespath==1.0.1" requests

Mantén tu clave en el entorno, nunca en el código fuente:

bash Copy
export SCRAPELESS_API_KEY="sk_tu_clave_de_scrapeless"

Obtener una API JSON a través de Scrapeless

La capa de obtención devuelve el JSON sin procesar. Debido a que el punto final proporciona JSON en lugar de una página renderizada, js_render se mantiene desactivado; la API de Scrapeless gestiona la solicitud, el enrutamiento de proxy y cualquier control de acceso delante del punto final, y devuelve el cuerpo definido por el estándar de semántica HTTP. Decodifícalo una vez y jmespath toma el control:

python Copy
# fetch.py — obtener una API JSON a través de Scrapeless, luego consultarla
import json
import os

import jmespath
import requests

resp = requests.post(
    "https://api.scrapeless.com/api/v2/unlocker/request",
    headers={"Content-Type": "application/json", "x-api-token": os.environ["SCRAPELESS_API_KEY"]},
    json={"actor": "unlocker.webunlocker", "input": {"url": "https://dummyjson.com/products?limit=10", "js_render": False}},
    timeout=120,
)
resp.raise_for_status()
payload = json.loads(resp.json()["data"])

print("productos en la página:", jmespath.search("length(products)", payload))
print("primer título:", jmespath.search("products[0].title", payload))
print("total disponible:", jmespath.search("total", payload))

La ejecución lee la forma de la respuesta sin un solo bucle:

text Copy
productos en la página: 10
primer título: Essence Mascara Lash Princess
total disponible: 194

La llamada de Scrapeless es la capa de obtención — la API Universal de Raspado devuelve el cuerpo JSON, y payload es ahora un objeto de Python simple que jmespath puede consultar.

Rediseñar y filtrar con jmespath

El objetivo de jmespath es convertir una respuesta voluminosa en exactamente los registros que deseas. Una proyección con un hash de multiselección reconstruye cada producto; una expresión de filtro mantiene solo las coincidencias; sort_by los ordena — todo como expresiones, no como código procedural:

python Copy
# query.py — rediseñar, filtrar y ordenar en tres expresiones
import json
import os

import jmespath
import requests

resp = requests.post(
```text
"https://api.scrapeless.com/api/v2/unlocker/request",
    headers={"Content-Type": "application/json", "x-api-token": os.environ["SCRAPELESS_API_KEY"]},
    json={"actor": "unlocker.webunlocker", "input": {"url": "https://dummyjson.com/products?limit=10", "js_render": False}},
    timeout=120,
)
resp.raise_for_status()
payload = json.loads(resp.json()["data"])

records = jmespath.search("products[].{title: title, price: price, rating: rating}", payload)
under_50 = jmespath.search("products[?price < `50`].title", payload)
cheapest = jmespath.search("sort_by(products, &price)[0].{title: title, price: price}", payload)

print("registros:", len(records))
print("primer registro:", json.dumps(records[0], ensure_ascii=False))
print("menos de $50:", len(under_50))
print("más barato:", json.dumps(cheapest, ensure_ascii=False))

Cada línea es una consulta que realiza el trabajo de un bucle:

text Copy
registros: 10
primer registro: {"title": "Essence Mascara Lash Princess", "price": 9.99, "rating": 2.56}
menos de $50: 6
más barato: {"title": "Red Nail Polish", "price": 8.99}

Ese es el extractor completo: un POST para obtener el JSON, tres expresiones para darle forma. El hash de multiselección {title: title, price: price} es el que hace el trabajo: elimina los campos que no necesitas y renombra los que mantienes, por lo que lo que almacenas es exactamente lo que pediste.

Obtén tu clave API en el plan gratuito: app.scrapeless.com

Patrones avanzados

  • Filtra antes de proyectar. products[?rating > \4.5`].{title: title}` mantiene primero las coincidencias, luego las remodela; ordenar la tubería de esta manera mantiene la expresión legible y el resultado pequeño.
  • Aplana listas anidadas con []. Cuando los registros anidan sus propias listas, products[].reviews[].rating aplana cada calificación de revisión en todos los productos en una lista: el operador de aplanamiento hace lo que haría un bucle doble.
  • Conecta expresiones con |. products | length(@) y sort_by(@, &price) | [0] encadenan un resultado a la siguiente expresión; @ es el nodo actual, que es cómo alimentas la salida de una consulta a otra.
  • Protege contra claves faltantes. jmespath devuelve None para una ruta que está ausente en lugar de generar un error, por lo que un campo que solo algunos registros llevan no hará que la consulta falle: verifica si es None cuando lo almacenas.

Solución de problemas

  • json.loads genera un error en la respuesta. El endpoint devolvió HTML, no JSON: a menudo es una página de error o bloqueo. Confirma que la URL es la API JSON y no la página HTML que la llama, y que la recuperación tuvo éxito antes de decodificar.
  • Una proyección devuelve una lista vacía. La ruta no coincide con la forma del documento. Imprime las claves de nivel superior y baja un nivel a la vez; las API JSON anidan sus arreglos bajo una clave como products o results, no en la raíz.
  • Un filtro no coincide con nada. Se requieren literales de comillas invertidas para números y cadenas en un filtro: price < \50`, no price < 50`. Sin las comillas invertidas, el valor se lee como un nombre de campo.
  • El resultado mantiene campos que no querías. Usaste una proyección simple products[] en lugar de un hash de multiselección. Agrega .{title: title, price: price} para seleccionar solo los campos que deseas conservar.

Conclusión

jmespath se gana su lugar como la capa que convierte una respuesta JSON en registros sin código procedural: proyecciones, filtros y ordenamientos como expresiones únicas. La capa que obtiene el JSON es la obtención: una API backend es la fuente más limpia que existe, y un POST de Scrapeless devuelve su cuerpo más allá de cualquier protección que tenga el endpoint. Conecta las dos y un feed de productos verboso se convierte en los cuatro campos que realmente almacenas.

Crea una cuenta gratuita en Scrapeless para obtener una clave API, y la documentación para desarrolladores cubre los parámetros de unlocker.webunlocker. Consulta los precios de Scrapeless cuando planifiques un trabajo recurrente.

Preguntas frecuentes

P: ¿Puede jmespath raspar sitios web por sí mismo?

No. jmespath consulta un valor JSON que ya tienes; no tiene cliente HTTP y no recupera URLs ni analiza HTML. Combínalo con una capa de recuperación: aquí la API Universal Scraping de Scrapeless, que devuelve el cuerpo JSON, y jmespath lo remodela en registros.

P: ¿Por qué raspar una API JSON en lugar de la página HTML?

Porque los datos llegan ya estructurados. Muchas páginas se generan a partir de un endpoint JSON que llaman en segundo plano; acceder a ese endpoint omite por completo el análisis HTML y el mantenimiento de selectores, y jmespath convierte la respuesta en exactamente los registros que deseas.

P: ¿Cómo es jmespath diferente de jsonpath?

Copy
Ambos consultan JSON, pero jmespath tiene una especificación formal y un lenguaje de expresión compacto con proyecciones, filtros, funciones y hashes de multiselección que remodelan la salida. Su sintaxis de multiselección — renombrar y eliminar campos en la consulta — es la característica que lo convierte en una buena opción para la extracción.

**P: ¿Qué pasa si el sitio no tiene una API JSON?**

Entonces analiza el HTML en su lugar: recupera la página renderizada a través de Scrapeless y usa una biblioteca de selectores. jmespath solo se aplica cuando la fuente es JSON; los dos enfoques cubren las dos formas en que los datos llegan.

**P: ¿Es legal raspar una API JSON?**

El lenguaje de consulta no cambia las reglas de recopilación. Recupera solo puntos finales públicos, respeta los términos del sitio y las directivas de robots estandarizadas por <a href="https://datatracker.ietf.org/doc/html/rfc9309" rel="nofollow"><strong>el Protocolo de Exclusión de Robots</strong></a>, mantén los volúmenes limitados y maneja cualquier dato personal bajo las leyes que te sean aplicables.

En Scrapeless, solo accedemos a datos disponibles públicamente y cumplimos estrictamente con las leyes, regulaciones y políticas de privacidad del sitio web aplicables. El contenido de este blog es sólo para fines de demostración y no implica ninguna actividad ilegal o infractora. No ofrecemos garantías y renunciamos a toda responsabilidad por el uso de la información de este blog o enlaces de terceros. Antes de realizar cualquier actividad de scraping, consulte a su asesor legal y revise los términos de servicio del sitio web de destino u obtenga los permisos necesarios.

Artículos más populares

Catalogar