En este tutorial, se explica:
- Qué es JSON y cómo manejarlo en Python
- Cómo analizar JSON en Python con el módulo json
- Si json es la mejor opción para analizar JSON
Introducción a JSON en Python
Antes de profundizar en el análisis JSON con Python, vamos a entender qué es JSON y cómo usarlo en Python.
¿Qué es JSON?
JSON, abreviatura de JavaScript Object Notation, es un formato ligero de intercambio de datos. Es sencillo de leer y escribir para los humanos y fácil de analizar y generar para las máquinas. Esto lo convierte en uno de los formatos de datos más populares. Concretamente, JSON se ha convertido en el “lenguaje de la web” porque se utiliza habitualmente para transmitir datos entre servidores y aplicaciones web a través de API.
He aquí un ejemplo de JSON:
{
"name": "Maria Smith",
"age": 32,
"isMarried": true,
"hobbies": ["reading", "jogging"],
"address": {
"street": "123 Main St",
"city": "San Francisco",
"state": "CA",
"zip": "12345"
},
"phoneNumbers": [
{
"type": "home",
"number": "555-555-1234"
},
{
"type": "work",
"number": "555-555-5678"
}
],
"notes": null
}
Como se puede ver, JSON consiste en pares clave-valor. Cada clave es una cadena y cada valor puede ser una cadena, un número, un booleano, un null, un array o un objeto. Aunque es similar a un objeto JavaScript, JSON puede utilizarse con cualquier lenguaje de programación, incluyendo Python.
Cómo tratar con JSON en Python
Python soporta JSON de forma nativa a través del módulo json, que forma parte de la Biblioteca Estándar de Python. Esto significa que no es necesario instalar ninguna biblioteca adicional para trabajar con JSON en Python. Se puede importar json de la siguiente manera:
import json
La biblioteca Python json incorporada expone una API completa para tratar con JSON. En particular, tiene dos funciones clave: loads
y load
. La función loads permite analizar datos JSON a partir de una cadena. Tengamos en cuenta que, a pesar de que su nombre parece ser plural, la terminación “s” significa “cadena”. Por lo tanto, debe leerse como “load-s”. Por otro lado, la función load es para analizar datos JSON en bytes.
A través de estos dos métodos, json
ofrece la posibilidad de convertir datos JSON en objetos Python equivalentes, como diccionarios y listas, y viceversa. Además, el módulo json permite crear codificadores y decodificadores personalizados para manejar tipos de datos específicos.
Continúe leyendo y descubra cómo utilizar la biblioteca json
para analizar datos JSON en Python.
Análisis sintáctico de datos JSON con Python
Veamos algunos ejemplos verídicos y aprendamos a analizar datos JSON de diferentes fuentes en diferentes estructuras de datos Python.
Convertir una Cadena JSON en un Diccionario Python
Supongamos que disponemos de algunos datos JSON almacenados en una cadena y queremos convertirlos en un diccionario Python. Así es como se ven los datos JSON:
{
"name": "iPear 23",
"colors": ["black", "white", "red", "blue"],
"price": 999.99,
"inStock": true
}
Y esta es su representación en Python:
smartphone_json = '{"name": "iPear 23", "colors": ["black", "white", "red", "blue"], "price": 999.99, "inStock": true}'
Considere usar la convención de Python de comillas triples para almacenar cadenas JSON largas de varias líneas.
Se puede verificar que smartphone contiene una cadena válida en Python con la línea de abajo:
print(type(smartphone))
Esto imprimirá:
<class 'str'>
str
significa “cadena” y significa que la variable smartphone tiene el tipo de secuencia de texto.
Analice la cadena JSON contenida en smartphone en un diccionario Python con el método json.loads() de la siguiente manera:
import json
# JSON string
smartphone_json = '{"name": "iPear 23", "colors": ["black", "white", "red", "blue"], "price": 999.99, "inStock": true}'
# from JSON string to Python dict
smartphone_dict = json.loads(smartphone_json)
# verify the type of the resulting variable
print(type(smartphone_dict)) # dict
Si se ejecuta este fragmento, se obtendría:
<class 'dict'>
¡Fantástico! ¡smartphone_dict
contiene ahora un diccionario Python válido!
Así, todo lo que es necesario hacer para convertir una cadena JSON en un diccionario Python es pasar una cadena JSON válida a json.loads()
Ahora se puede acceder a los campos del diccionario resultante de la forma habitual:
product = smartphone_dict['product'] # smartphone
priced = smartphone['price'] # 999.99
colors = smartphone['colors'] # ['black', 'white', 'red', 'blue']
Sin embargo, tenga en cuenta que la función json.loads()
no siempre devuelve un diccionario. En concreto, el tipo de datos devuelto depende de la cadena de entrada. Por ejemplo, si la cadena JSON contiene un valor plano, se convertirá al valor primitivo Python correspondiente:
import json
json_string = '15.5'
float_var = json.loads(json_string)
print(type(float_var)) # <class 'float'>
Del mismo modo, una cadena JSON que contenga una lista de matrices se convertirá en una lista de Python:
import json
json_string = '[1, 2, 3]'
list_var = json.loads(json_string)
print(json_string) # <class 'list'>
Echa un vistazo a la tabla de conversión a continuación para ver cómo los valores de JSON se convierten en datos de Python mediante json
:
Valor JSON
|
Datos Python
|
string |
str |
number (integer) |
int |
number (real) |
float |
true |
True |
false |
False |
null |
None |
array |
list |
object |
dict |
Transformando una Respuesta API JSON en un Diccionario Python
Consideremos que necesitamos realizar una API y convertir su respuesta JSON en un diccionario Python. En el siguiente ejemplo, llamaremos al siguiente endpoint de la API desde el proyecto {JSON} para obtener algunos datos JSON falsos:
https://jsonplaceholder.typicode.com/todos/1
Esa API RESTFul devuelve la respuesta JSON de abajo:
{
"userId": 1,
"id": 1,
"title": "delectus aut autem",
"completed": false
}
Se puede llamar a esa API con el módulo urllib
de la Biblioteca Estándar y convertir el JSON resultante en un diccionario Python de la siguiente manera:
import urllib.request
import json
url = "https://jsonplaceholder.typicode.com/todos/1"
with urllib.request.urlopen(url) as response:
body_json = response.read()
body_dict = json.loads(body_json)
user_id = body_dict['userId'] # 1
urllib.request.urlopen()
realiza la llamada a la API y devuelve un objeto HTTPResponse
. Su método read()
se utiliza para obtener el cuerpo de la respuesta body_json, que contiene la respuesta de la API como una cadena JSON. Finalmente, esa cadena puede analizarse en un diccionario Python a través de json.loads(), como se explicó anteriormente.
De igual manera, se puede lograr el mismo resultado con requests:
import requests
import json
url = "https://jsonplaceholder.typicode.com/todos/1"
response = requests.get(url)
body_dict = response.json()
user_id = body_dict['userId'] # 1
Ten en cuenta que el método .json()
transforma automáticamente el objeto de respuesta que contiene datos JSON en la estructura de datos de Python correspondiente.
¡Genial! Así es como se analiza una respuesta JSON de la API en Python, tanto con urllib
como con requests
.
Cargando un Archivo JSON en un Diccionario Python
Supongamos que existen algunos datos JSON almacenados en un archivo smartphone.json
como el que se muestra a continuación:
{
"name": "iPear 23",
"colors": ["black", "white", "red", "blue"],
"price": 999.99,
"inStock": true,
"dimensions": {
"width": 2.82,
"height": 5.78,
"depth": 0.30
},
"features": [
"5G",
"HD display",
"Dual camera"
]
}
El objetivo es leer el archivo JSON y cargarlo en un diccionario Python. Para ello, emplearemos el siguiente fragmento de código:
import json
with open('smartphone.json') as file:
smartphone_dict = json.load(file)
print(type(smartphone_dict)) # <class 'dict'>
features = smartphone_dict['features'] # ['5G', 'HD display', 'Dual camera']
La biblioteca incorporada open()
permite cargar un archivo y obtener su correspondiente objeto archivo. A continuación, el método json.read()
deserializa el archivo de texto o binario que contiene un documento JSON al objeto Python equivalente. En este caso, smartphone.json
se convierte en un diccionario Python.
Perfecto, ¡analizar un archivo JSON en Python sólo requiere unas cuantas líneas de código!
De Datos JSON a Objeto Python Personalizado
Ahora, quieres analizar algunos datos JSON en una clase personalizada de Python. Así es como se ve tu clase personalizada de Python para Smartphone
:
class Smartphone:
def __init__(self, name, colors, price, in_stock):
self.name = name
self.colors = colors
self.price = price
self.in_stock = in_stock
Aquí, el objetivo es convertir la siguiente cadena JSON en una instancia de Smartphone
:
{
"name": "iPear 23 Plus",
"colors": ["black", "white", "gold"],
"price": 1299.99,
"inStock": false
}
Para realizar esta tarea, se requiere crear un decodificador personalizado. En concreto, extender la clase JSONDecoder
y establecer el parámetro object_hook
en el método __init__
. Se le asigna el nombre del método de la clase que contiene la lógica de análisis personalizada. En ese método de análisis, se pueden utilizar los valores contenidos en el diccionario estándar devuelto por json.read()
para instanciar un objeto Smartphone
.
A continuación, se define un SmartphoneDecoder
personalizado:
import json
class SmartphoneDecoder(json.JSONDecoder):
def __init__(self, object_hook=None, *args, **kwargs):
# set the custom object_hook method
super().__init__(object_hook=self.object_hook, *args, **kwargs)
# class method containing the
# custom parsing logic
def object_hook(self, json_dict):
new_smartphone = Smartphone(
json_dict.get('name'),
json_dict.get('colors'),
json_dict.get('price'),
json_dict.get('inStock'),
)
return new_smartphone
Nótese que se debe utilizar el método get()
para leer los valores del diccionario dentro del método personalizado object_hook()
. Esto asegurará que no se produzcan KeyErrors
si falta una clave en el diccionario. En su lugar, se devolverán los valores None
.
Ahora se puede pasar la clase SmartphoneDecoder
al parámetro cls
en json.loads()
para convertir una cadena JSON en un objeto Smartphone
:
import json
# class Smartphone:
# ...
# class SmartphoneDecoder(json.JSONDecoder):
# ...
smartphone_json = '{"name": "iPear 23 Plus", "colors": ["black", "white", "gold"], "price": 1299.99, "inStock": false}'
smartphone = json.loads(smartphone_json, cls=SmartphoneDecoder)
print(type(smartphone)) # <class '__main__.Smartphone'>
name = smartphone.name # iPear 23 Plus
Del mismo modo, se puede utilizar SmartphoneDecoder
con json.load()
:
smartphone = json.load(smartphone_json_file, cls=SmartphoneDecoder)
¡Et voilà! Así es como se convierte datos JSON en objetos Python personalizados.
Datos Python a JSON
También puede hacerse a la inversa y convertir estructuras de datos y primitivas de Python a JSON. Esto es posible gracias a las funciones json.dump()
y json.dumps()
, que se muestran en la siguiente tabla de conversión:
Datos Python
|
Valor JSON
|
str |
string |
int |
number (integer) |
float |
number (real) |
True |
true |
False |
false |
None |
null |
list |
array |
dict |
object |
Null |
Ninguno |
json.dump()
permite escribir una cadena JSON en un archivo, como en el siguiente ejemplo:
import json
user_dict = {
"name": "John",
"surname": "Williams",
"age": 48,
"city": "New York"
}
# serializing the sample dictionary to a JSON file
with open("user.json", "w") as json_file:
json.dump(user_dict, json_file)
Este fragmento serializará la variable user_dict
de Python en el archivo user.json
.
De la misma manera, json.dumps()
convierte una variable Python en su cadena JSON equivalente:
import json
user_dict = {
"name": "John",
"surname": "Williams",
"age": 48,
"city": "New York"
}
user_json_string = json.dumps(user_dict)
print(user_json_string)
Ejecute este fragmento y obtendrá:
Esta es exactamente la representación JSON del dict Python.
Cabe destacar que también es posible especificar un codificador personalizado, pero mostrar cómo hacerlo no es el propósito de este artículo. Siga la documentación oficial para aprender más.
¿Es el Módulo Estándar json
el Mejor Recurso para Analizar JSON en Python?
Como sucede en general con el análisis sintáctico de datos, el análisis sintáctico de JSON presenta desafíos que no pueden pasarse por alto. Por ejemplo, en caso de JSON inválido, roto o no estándar, el módulo json
de Python se quedaría corto.
Además, es necesario tener cuidado al analizar datos JSON de fuentes no confiables. Esto se debe a que una cadena JSON maliciosa puede hacer que el analizador se rompa o consuma una gran cantidad de recursos. Este es sólo uno de los retos que un analizador JSON de Python debe tener en cuenta.
Se podría introducir lógica personalizada para tratar estos casos particulares. Al mismo tiempo, eso podría llevar demasiado tiempo y resultar en un código complejo y poco fiable. Por esta razón, es recomendable considerar una herramienta comercial que facilite el análisis JSON, como el IDE Web Scraper.
El IDE Web Scraper está diseñado específicamente para desarrolladores y viene con una amplia gama de características para analizar contenido JSON y más. Esta herramienta puede ahorrarle mucho tiempo y ayudarle a asegurar su proceso de análisis JSON. Además, viene con capacidades de proxy de desbloqueo de Bright Data para llamar a APIs JSON de forma anónima.
Si tiene prisa, podría también interesarle nuestra oferta Data as a Service. A través de este servicio, puede pedir a Bright Data que le proporcione un conjunto de datos personalizado que se ajuste a sus necesidades específicas. Bright Data se encargará de todo, desde el rendimiento hasta la calidad de los datos.
¡Analizar datos JSON nunca ha sido tan fácil!
Conclusión
Python le permite analizar datos JSON de forma nativa a través del módulo estándar json
. Esto expone una potente API para serializar y deserializar contenido JSON. Específicamente, ofrece los métodos json.read()
y json.reads()
para tratar con archivos JSON y cadenas JSON, respectivamente. En este artículo, se ha explicado cómo utilizarlos para analizar datos JSON en Python en varios ejemplos reales. También se abordaron las limitaciones de este enfoque. Por ello, es posible que sea conveniente probar una solución comercial de vanguardia, con todas las funciones, para el análisis sintáctico de datos, como el IDE Web Scraper de Bright Data.