JMESPath Web Scraping: Consultando APIs JSON de Forma Declarativa
Advanced Data Extraction Specialist
Resumo:
- jmespath consulta JSON de maneira declarativa. Uma expressão remodela uma resposta de API aninhada em registros planos — sem loops, sem caminhadas manuais no dicionário.
- APIs JSON são o alvo de raspagem mais limpo. Muitos sites constroem suas páginas a partir de um endpoint JSON no backend; busque esse JSON e os dados chegam já estruturados.
- O que jmespath não faz é buscar. Ele não possui cliente HTTP e não analisa HTML; você fornece um objeto JSON decodificado e ele o consulta.
- Busque através do Scrapeless quando a API é protegida. Uma execução ao vivo puxou uma API de produtos através da Scrapeless Universal Scraping API, depois usou jmespath para selecionar, filtrar e classificar os resultados.
- Filtros e projeções em uma linha.
products[?price < \50`].titleretornou os seis produtos abaixo de $50;sort_by(products, &price)[0]` retornou o mais barato. - Gratuito para começar do lado da busca. Crie sua chave de API Scrapeless em app.scrapeless.com.
O que é jmespath e o que não é
jmespath é uma linguagem de consulta para JSON. Você escreve uma expressão que descreve a forma que deseja, e a biblioteca percorre o documento e a retorna — projeções extraem um campo de cada elemento de uma lista, filtros mantêm apenas os elementos que correspondem a uma condição, e hashes de multiselect reconstroem cada elemento em um registro menor. É a mesma linguagem de expressão que a AWS CLI usa para seu sinalizador --query, padronizada pela especificação JMESPath, e disponível como uma pequena biblioteca Python.
É uma linguagem de consulta, não um raspador. jmespath não possui cliente HTTP, não busca URLs e não analisa HTML — ele opera em um valor JSON que você já decodificou, definido pelo padrão de intercâmbio de dados JSON. Portanto, uma configuração de "raspagem web jmespath" possui duas camadas: algo que retorna o JSON e jmespath que o remodela. Isso é importante porque uma grande parte dos dados em sites modernos é fornecida por uma API JSON no backend que a página chama em segundo plano; acessar esse endpoint diretamente evita completamente a análise HTML. Quando o endpoint é geograficamente restrito ou limitado por taxa, este guia o busca através da Scrapeless Universal Scraping API. Para o lado de HTML da raspagem, o tutorial de raspagem web em Python cobre seletores.
Instalar
jmespath e requests são toda a cadeia de ferramentas. A versão para a qual este guia foi escrito é jmespath 1.0.1:
bash
pip install "jmespath==1.0.1" requests
Mantenha sua chave no ambiente, nunca no código-fonte:
bash
export SCRAPELESS_API_KEY="sk_sua_chave_scrapeless"
Buscar uma API JSON através do Scrapeless
A camada de busca retorna o JSON bruto. Como o endpoint fornece JSON em vez de uma página renderizada, js_render fica desligado; a API Scrapeless cuida da solicitação, roteamento do proxy e quaisquer controles de acesso na frente do endpoint, e retorna o corpo definido pelo padrão de semântica HTTP. Decodifique-o uma vez e jmespath assume o controle:
python
# fetch.py — puxe uma API JSON através do Scrapeless, depois consulte
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("produtos na página:", jmespath.search("length(products)", payload))
print("primeiro título:", jmespath.search("products[0].title", payload))
print("total disponível:", jmespath.search("total", payload))
A execução lê a forma da resposta sem um único loop:
text
produtos na página: 10
primeiro título: Essence Mascara Lash Princess
total disponível: 194
A chamada do Scrapeless é a camada de busca — a Universal Scraping API retorna o corpo JSON, e payload agora é um objeto Python simples que jmespath pode consultar.
Remodelar e filtrar com jmespath
O objetivo do jmespath é transformar uma resposta verbosa exatamente nos registros que você deseja. Uma projeção com um hash de multiselect reconstrói cada produto; uma expressão de filtro mantém apenas as correspondências; sort_by os ordena — tudo isso como expressões, não como código procedural:
python
# query.py — remodelar, filtrar e classificar em três expressões
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"])
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("records:", len(records))
print("first record:", json.dumps(records[0], ensure_ascii=False))
print("under $50:", len(under_50))
print("cheapest:", json.dumps(cheapest, ensure_ascii=False))
Cada linha é uma consulta que faz o trabalho de um loop:
text
records: 10
first record: {"title": "Essence Mascara Lash Princess", "price": 9.99, "rating": 2.56}
under $50: 6
cheapest: {"title": "Red Nail Polish", "price": 8.99}
Esse é o extractor completo: um POST para buscar o JSON, três expressões para moldá-lo. O hash de multiseleção {title: title, price: price} é a peça central — ele descarta os campos que você não precisa e renomeia os que você mantém, para que o que você armazena seja exatamente o que você pediu.
Obtenha sua chave de API no plano gratuito: app.scrapeless.com
Padrões Avançados
- Filtrar antes de projetar.
products[?rating > \4.5`].{title: title}` mantém as correspondências primeiro e depois as remodela; ordenar o pipe dessa maneira mantém a expressão legível e o resultado pequeno. - Desencadear listas aninhadas com
[]. Quando registros aninham suas próprias listas,products[].reviews[].ratingachata todas as avaliações de cada produto em uma única lista — o operador de achatamento faz o que um loop duplo faria. - Vincular expressões com
|.products | length(@)esort_by(@, &price) | [0]encadeiam um resultado na próxima expressão;@é o nó atual, que é como você alimenta a saída de uma consulta em outra. - Proteger contra chaves faltantes. jmespath retorna
Nonepara um caminho que está ausente, em vez de levantar um erro, então um campo que apenas alguns registros carregam não irá falhar a consulta — verifique se éNoneao armazená-lo.
Resolução de Problemas
json.loadslança uma exceção na resposta. O endpoint retornou HTML, não JSON — muitas vezes uma página de erro ou bloqueio. Confirme se a URL é a API JSON e não a página HTML que a chama, e que a busca foi bem-sucedida antes de decodificar.- Uma projeção retorna uma lista vazia. O caminho não corresponde à forma do documento. Imprima as chaves de nível superior e caminhe para baixo um nível de cada vez; APIs JSON aninham seus arrays sob uma chave como
productsouresults, não na raiz. - Um filtro não corresponde a nada. Literais de crase são necessários para números e strings em um filtro —
price < \50`, nãoprice < 50`. Sem as crases, o valor é lido como um nome de campo. - O resultado mantém campos que você não queria. Você usou uma projeção simples
products[]em vez de um hash de multiseleção. Adicione.{title: title, price: price}para selecionar apenas os campos a serem mantidos.
Conclusão
jmespath ganha seu lugar como a camada que transforma uma resposta JSON em registros sem código procedural: projeções, filtros e classificações como expressões únicas. A camada que obtém o JSON é a busca — uma API de backend é a fonte mais limpa que existe, e um POST do Scrapeless retorna seu corpo além de quaisquer proteções do endpoint. Conecte os dois e um feed de produto verboso se torna os quatro campos que você realmente armazena.
Crie uma conta gratuita no Scrapeless para obter uma chave de API, e a documentação para desenvolvedores cobre os parâmetros de unlocker.webunlocker. Verifique preços do Scrapeless quando você planeja um trabalho recorrente.
FAQ
Q: O jmespath pode raspar sites sozinho?
Não. o jmespath consulta um valor JSON que você já possui; ele não possui um cliente HTTP e não busca URLs ou analisa HTML. Combine-o com uma camada de busca — aqui a API de Raspagem Universal Scrapeless, que retorna o corpo JSON — e o jmespath remodela isso em registros.
Q: Por que raspar uma API JSON em vez da página HTML?
Porque os dados chegam já estruturados. Muitas páginas são renderizadas a partir de um endpoint JSON de backend que chamam em segundo plano; acessar esse endpoint evita completamente a análise de HTML e a manutenção de seletores, e o jmespath transforma a resposta exatamente nos registros que você deseja.
Q: Como o jmespath é diferente do jsonpath?
Ambos consultam JSON, mas jmespath possui uma especificação formal e uma linguagem de expressão compacta com projeções, filtros, funções e hashes de multiseleção que remodelam a saída. Sua sintaxe de multiseleção — renomeando e removendo campos na consulta — é o recurso que a torna adequada para extração.
Q: E se o site não tiver uma API JSON?
Então, faça o parsing do HTML em vez disso: recupere a página renderizada através do Scrapeless e use uma biblioteca de seletores. jmespath se aplica apenas quando a fonte é JSON; as duas abordagens cobrem as duas formas como os dados são apresentados.
Q: É legal fazer scraping de uma API JSON?
A linguagem de consulta não muda as regras de coleta. Busque apenas endpoints públicos, respeite os termos do site e as diretrizes de robôs padronizadas pelo Protocolo de Exclusão de Robôs, mantenha os volumes limitados e trate quaisquer dados pessoais de acordo com as leis que se aplicam a você.
Na Scorretless, acessamos apenas dados disponíveis ao público, enquanto cumprem estritamente as leis, regulamentos e políticas de privacidade do site aplicáveis. O conteúdo deste blog é apenas para fins de demonstração e não envolve atividades ilegais ou infratoras. Não temos garantias e negamos toda a responsabilidade pelo uso de informações deste blog ou links de terceiros. Antes de se envolver em qualquer atividade de raspagem, consulte seu consultor jurídico e revise os termos de serviço do site de destino ou obtenha as permissões necessárias.



