(+351) 21 24 10006  ·  info@bconcepts.pt
Carnaxide, Lisboa

Como transformar JSON de uma API num DataFrame pandas

João Barros 05 de July de 2026 4 min de leitura

As APIs de dados devolvem quase sempre JSON com estrutura aninhada, ou seja, dicionários dentro de dicionários. Esse formato é ótimo para transportar dados, mas mau para analisar: para filtrar, agrupar ou criar gráficos precisas de uma tabela plana. Transformar o JSON de uma API num DataFrame do pandas é exatamente esse passo, e a função pandas.json_normalize resolve-o em poucas linhas. A seguir vês como, com uma API pública real como exemplo.

Pré-requisitos

  • Python 3.9 ou superior instalado.
  • As bibliotecas pandas e requests (instala com pip install pandas requests).
  • Conhecimentos básicos de Python: variáveis, listas e dicionários.
  • Ligação à internet para chamar a API pública de exemplo.

Passo 1: Obter os dados da API

Como exemplo usamos uma API pública e gratuita que devolve uma lista de utilizadores, cada um com campos aninhados de morada e de empresa. Fazemos o pedido com requests, verificamos se correu bem com raise_for_status() e convertemos a resposta em objetos Python com .json().

import requests
import pandas as pd

url = "https://jsonplaceholder.typicode.com/users"
resposta = requests.get(url, timeout=10)
resposta.raise_for_status()  # lança um erro se o pedido falhar
dados = resposta.json()

print(type(dados), len(dados))
print(dados[0])

A variável dados é uma lista de dicionários. Repara que campos como address e company contêm, por sua vez, outros dicionários — é essa a estrutura aninhada que vamos aplanar no próximo passo.

Passo 2: Transformar o JSON num DataFrame

A função pandas.json_normalize percorre cada registo e cria uma coluna para todos os campos, incluindo os que estão aninhados. Por omissão, une os vários níveis com um ponto — por exemplo, o campo city dentro de address passa a chamar-se address.city.

df = pd.json_normalize(dados)

print(df.shape)
print(df.columns.tolist())

O resultado tem colunas como id, name, address.city, address.geo.lat e company.name. Num único passo, o JSON aninhado passou a uma tabela plana com uma linha por utilizador.

Dica: json_normalize aplana automaticamente todos os níveis de dicionários, por muito fundos que estejam. Não precisas de percorrer o JSON à mão.

Passo 3: Nomes de colunas mais limpos

O ponto nos nomes funciona, mas pode dar erro quando escreves código como df.address.city. Com o parâmetro sep escolhes outro separador, como o traço inferior, e a seguir ficas só com as colunas que interessam para a tua análise.

df = pd.json_normalize(dados, sep="_")

colunas = ["id", "name", "email", "address_city", "company_name"]
print(df[colunas].head())

Agora as colunas chamam-se address_city ou company_name, muito mais fáceis de usar no resto do trabalho.

Passo 4: Aplanar uma lista dentro do JSON

Muitas APIs não devolvem uma lista simples: devolvem um objeto com alguns metadados e a lista de registos lá dentro. Nesses casos, indica o caminho até à lista com record_path e os campos de nível superior que queres manter em cada linha com meta.

resposta_api = {
    "empresa": "bConcepts",
    "pais": "PT",
    "clientes": [
        {"id": 1, "nome": "Ana", "cidade": "Porto"},
        {"id": 2, "nome": "Bruno", "cidade": "Lisboa"},
    ],
}

df_clientes = pd.json_normalize(
    resposta_api,
    record_path="clientes",
    meta=["empresa", "pais"],
)
print(df_clientes)

O resultado tem uma linha por cliente e as colunas empresa e pais repetem-se em cada linha. É assim que juntas os registos detalhados à informação de contexto que veio no topo da resposta.

Verificar o resultado

Para confirmar que a conversão correu bem, verifica a forma da tabela, espreita as primeiras linhas e garante que já não sobrou nenhum dicionário por aplanar:

print(df.shape)   # (linhas, colunas)
print(df.head())

# Procurar colunas que ainda contenham dicionarios:
aninhadas = [c for c in df.columns if df[c].apply(lambda v: isinstance(v, dict)).any()]
print("Colunas ainda aninhadas:", aninhadas)

Se a lista aninhadas vier vazia, todos os campos foram aplanados e o DataFrame está pronto para análise.

Conclusão

Em poucas linhas transformaste o JSON de uma API numa tabela pronta a usar: obtiveste os dados, aplanaste os campos aninhados com json_normalize e arrumaste os nomes das colunas. A partir daqui podes guardar o resultado com df.to_csv("dados.csv", index=False), carregá-lo para uma base de dados ou combiná-lo com a paginação para trazer todas as páginas de uma vez. Qual será a próxima API que vais precisar de transformar num DataFrame?