La biblioteca Requests es la herramienta más popular de Python para trabajar con protocolos HTTP. Si necesitas consumir APIs, realizar web scraping, descargar archivos o integrar sistemas, Requests es la opción ideal por su simplicidad y potencia.
En esta guía completa, aprenderás desde la instalación hasta técnicas avanzadas como autenticación, sesiones persistentes y manejo de errores. Al final, tendrás el dominio completo para trabajar con cualquier tipo de solicitud HTTP en Python.
Instalación y Configuración
Requests no viene incluido en la biblioteca estándar de Python, así que necesitas instalarlo vía pip. La instalación es extremadamente sencilla:
# Instalando vía pip
pip install requests
O usando pip3 en sistemas Linux/Mac
pip3 install requests
Para verificar que la instalación fue exitosa, puedes importar el módulo y verificar su versión:
import requests
print(requests.version)
La biblioteca es mantenida por la comunidad de Python y tiene excelente documentación oficial. Puedes consultar la documentación completa en requests.readthedocs.io.
Realizando tu Primera Solicitud GET
La solicitud GET es el método más básico y común para obtener datos de un servidor. Con Requests, hacer una solicitud GET es increíblemente simple:
import requests
Solicitud GET simple
response = requests.get("https://api.github.com")
Verificando el estado de la respuesta
print(f"Status Code: {response.status_code}")
print(f"Reason: {response.reason")
Visualizando el contenido (texto)
print(response.text[:500])
El objeto response contiene diversa información sobre la respuesta del servidor:
status_code: Código de estado HTTP (200 = OK, 404 = Not Found, etc)reason: Frase descriptiva del estado ("OK", "Not Found", etc)text: Contenido de la respuesta en formato textojson(): Contenido parseado como JSONheaders: Encabezados de la respuestacookies: Cookies recibidas
Verificando el Estado de Forma Segura
Es una buena práctica verificar que la solicitud fue exitosa antes de procesar los datos. Requests facilita esto con el atributo ok:
import requests
response = requests.get("https://api.github.com")
if response.ok:
print("¡Solicitud exitosa!")
data = response.json()
print(data)
else:
print(f"Error: {response.status_code} - {response.reason}")
Trabajando con Parámetros de Query
Muchas APIs utilizan parámetros de query string para filtrar o paginar resultados. Requests permite pasar estos parámetros de manera organizada:
import requests
Parámetros de query pasados como diccionario
params = {
"page": 1,
"per_page": 10,
"sort": "created",
"direction": "desc"
}
response = requests.get(
"https://api.github.com/repos/python/cpython/releases",
params=params
)
print(f"URL generada: {response.url}")
print(f"Estado: {response.status_code}")
Viendo los datos JSON retornados
releases = response.json()
for release in releases[:3]:
print(f"- {release['tag_name']}: {release['name']}")
Este enfoque es mucho más limpio que concatenar strings manualmente, ya que Requests maneja automáticamente la codificación URL.
Enviando Datos con POST
El método POST se utiliza para enviar datos al servidor, ya sea para crear nuevos recursos, enviar formularios o cargar payloads JSON:
import requests
Datos para enviar (diccionario Python)
data = {
"username": "usuario_prueba",
"email": "[email protected]",
"password": "contrasena_segura123"
}
Enviando POST con datos de formulario
response = requests.post(
"https://httpbin.org/post",
data=data
)
print(f"Estado: {response.status_code}")
print(response.json())
Enviando JSON en el Cuerpo de la Solicitud
Muchas APIs modernas esperan recibir datos en formato JSON. Puedes usar el parámetro json para esto:
import requests
Payload JSON
payload = {
"title": "Nueva Publicación",
"body": "Contenido de la publicación aquí",
"userId": 1
}
response = requests.post(
"https://jsonplaceholder.typicode.com/posts",
json=payload
)
La respuesta ya viene en JSON automáticamente
result = response.json()
print(f"ID creado: {result['id']}")
print(f"Título: {result['title']}")
Requests automáticamente define el header Content-Type como application/json cuando usas el parámetro json.
Headers Personalizados
En algunas situaciones, necesitas enviar encabezados personalizados en la solicitud, como tokens de autenticación, identificación de aplicación o preferencias de formato:
import requests
Definiendo headers personalizados
headers = {
"Authorization": "Bearer tu_token_aqui",
"Accept": "application/json",
"User-Agent": "MiApp/1.0",
"Accept-Language": "es-ES,es;q=0.9"
}
response = requests.get(
"https://api.ejemplo.com/datos-protegidos",
headers=headers
)
print(f"Estado: {response.status_code}")
print(response.json())
Autenticación con Requests
Requests soporta de forma nativa varios métodos de autenticación. Los más comunes son Basic Auth y Bearer Token:
Autenticación Básica
import requests
from requests.auth import HTTPBasicAuth
Autenticación Basic (usuario y contraseña)
auth = HTTPBasicAuth("usuario", "contrasena")
response = requests.get(
"https://httpbin.org/basic-auth/usuario/contrasena",
auth=auth
)
print(f"Estado: {response.status_code}")
print(response.text)
Bearer Token (JWT)
import requests
Bearer Token para APIs que usan JWT
headers = {
"Authorization": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
response = requests.get(
"https://api.ejemplo.com/usuario/perfil",
headers=headers
)
print(response.json())
Para autenticación más compleja, puedes implementar tu propia clase de autenticación heredando de requests.auth.AuthBase. La documentación oficial sobre autenticación está disponible en docs.python-requests.org.
Trabajando con Cookies y Sesiones
Las cookies son fundamentales para mantener estado entre solicitudes, como sesiones de usuario. Requests facilita el trabajo con cookies:
import requests
Verificando cookies de la respuesta
response = requests.get("https://httpbin.org/cookies")
print("Cookies recibidas:")
print(response.json())
Enviando cookies personalizadas
cookies = {
"session_id": "abc123xyz",
"user_preference": "dark_mode"
}
response = requests.get(
"https://httpbin.org/cookies",
cookies=cookies
)
print(response.json())
Usando Sesiones Persistentes
Cuando necesitas hacer múltiples solicitudes manteniendo los mismos cookies y configuraciones, usar una Session es mucho más eficiente:
import requests
Crear una sesión
session = requests.Session()
La sesión mantiene cookies automáticamente entre solicitudes
session.headers.update({
"User-Agent": "MiBot/1.0"
})
Primera solicitud - login
login_data = {"username": "admin", "password": "123456"}
response = session.post("https://ejemplo.com/login", data=login_data)
print(f"Login: {response.status_code}")
Segunda solicitud - ya autenticado
response = session.get("https://ejemplo.com/dashboard")
print(f"Dashboard: {response.status_code}")
Tercera solicitud - continuar usando la sesión
response = session.get("https://ejemplo.com/perfil")
print(f"Perfil: {response.status_code}")
La sesión también permite compartir conexiones TCP, mejorando el rendimiento en múltiples solicitudes. Para más detalles sobre sesiones, consulta la documentación avanzada.
Timeouts y Manejo de Errores
Por defecto, Requests espera indefinidamente por una respuesta. Es crucial definir timeouts para evitar que tu aplicación se cuelgue:
import requests
from requests.exceptions import Timeout, ConnectionError
Timeout de 5 segundos (conexión y lectura)
try:
response = requests.get(
"https://api.ejemplo.com/datos",
timeout=5
)
print(response.json())
except Timeout:
print("¡Tiempo límite excedido!")
except ConnectionError:
print("¡Error de conexión!")
except requests.exceptions.RequestException as e:
print(f"Error general: {e}")
Excepciones Disponibles
Requests lanza varias excepciones que puedes capturar:
requests.exceptions.RequestException: Clase base para todas las excepcionesrequests.exceptions.ConnectionError: Error de conexión de redrequests.exceptions.Timeout: Tiempo límite excedidorequests.exceptions.HTTPError: Respuesta HTTP con error (4xx o 5xx)requests.exceptions.TooManyRedirects: Exceso de redirecciones
Verificando Errores HTTP Automáticamente
También puedes configurar Requests para lanzar excepciones automáticamente en errores HTTP:
import requests
from requests.exceptions import HTTPError
Configurar para lanzar excepciones en estados de error
response = requests.get("https://httpbin.org/status/404")
response.raise_for_status() # Lanza HTTPError para 4xx/5xx
Descarga de Archivos y Streaming de Datos
Para archivos grandes, no quieres cargar todo en memoria de una vez. Requests permite hacer streaming de datos:
import requests
Streaming de descarga - no carga todo en memoria
url = "https://example.com/archivo-grande.zip"
response = requests.get(url, stream=True)
Obtener tamaño total (si está disponible)
total_size = response.headers.get("content-length")
print(f"Tamaño total: {total_size} bytes")
Descargar en chunks
with open("archivo.zip", "wb") as f:
for chunk in response.iter_content(chunk_size=8192):
if chunk:
f.write(chunk)
print("¡Descarga completada!")
La técnica de streaming es esencial para archivos grandes o para procesar datos en tiempo real. Para descargar imágenes u otros archivos binarios, Requests detecta automáticamente el tipo de contenido.
Retry y Estrategia de Reintentos
En aplicaciones de producción, frecuentemente necesitas reintentar solicitudes que fallaron temporalmente:
import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
Configurar estrategia de reintentos
session = requests.Session()
retry_strategy = Retry(
total=3,
backoff_factor=1,
status_forcelist=[429, 500, 502, 503, 504],
allowed_methods=["GET", "POST"]
)
adapter = HTTPAdapter(max_retries=retry_strategy)
session.mount("http://", adapter)
session.mount("https://", adapter)
Ahora las solicitudes se reintentarán automáticamente
response = session.get("https://api.ejemplo.com/datos")
print(f"Estado: {response.status_code}")
Esta configuración hace que la solicitud se reintente hasta 3 veces, con backoff exponencial entre intentos, solo para errores de servidor (5xx) o rate limiting (429).
Timeout Adaptativo con Sesión
Para aplicaciones que hacen muchas solicitudes, puedes configurar timeouts por defecto en la sesión:
import requests
session = requests.Session()
Configurar timeout por defecto para todas las solicitudes
session.timeout = 10
Timeout específico para una solicitud
response = session.get("https://api.ejemplo.com", timeout=30)
print(response.status_code)
Verificación de SSL
Por defecto, Requests verifica certificados SSL. En entornos de desarrollo, puedes necesitar deshabilitar esta verificación:
import requests
Deshabilitar verificación SSL (¡NO usar en producción!)
response = requests.get(
"https://ejemplo.com",
verify=False
)
Para ignorar solo certificados específicos
response = requests.get("https://ejemplo.com", verify="/path/to/cert.pem")
Advertencia importante: Nunca deshabilites la verificación SSL en producción, ya que esto expone tu aplicación a ataques man-in-the-middle.
Integración con Web Scraping
Requests frecuentemente se usa junto con BeautifulSoup para web scraping. Después de obtener el HTML con Requests, puedes parsearlo con BeautifulSoup:
import requests
from bs4 import BeautifulSoup
Obtener página HTML
response = requests.get("https://ejemplo.com/articulos")
response.encoding = "utf-8"
Parsear el HTML
soup = BeautifulSoup(response.text, "html.parser")
Extraer títulos de los artículos
for article in soup.select("article"):
title = article.select_one("h2").text
link = article.select_one("a")["href"]
print(f"{title} -> {link}")
Si quieres aprender más sobre web scraping, tenemos una guía completa de web scraping con Python que explora técnicas más avanzadas.
Buenas Prácticas y Rendimiento
Para usar Requests de manera eficiente en producción, sigue estas prácticas:
- Usa Sesión: Reutiliza conexiones TCP con sesiones para mejor rendimiento
- Define Timeouts: Siempre define timeouts para evitar cuelgues
- Maneja Errores: Captura excepciones apropiadamente
- Usa Retry: Implementa reintentos con backoff para errores transitorios
- Reutiliza Conexiones: Configura connection pooling para muchas solicitudes
- Registra Solicitudes: Añade logging para depuración en producción
Recursos Adicionales
Para profundizar tu conocimiento sobre Requests y HTTP en general, aquí tienes algunos recursos confiables:
- Documentación oficial de Requests
- MDN Web Docs - HTTP
- Python.org
- HTTPBin - Herramienta de prueba
- JSONPlaceholder - API de prueba
- Real Python - Tutorial de Requests
- W3C - Especificación HTTP
- urllib - Biblioteca estándar de Python
Conclusión
La biblioteca Requests es esencial para cualquier desarrollador de Python que necesita trabajar con APIs, realizar web scraping o integrar sistemas. Con su API intuitiva y potente, puedes realizar desde solicitudes simples hasta configuraciones avanzadas de autenticación, sesiones y reintentos.
Ahora que dominas Requests, explora nuestra guía completa de Python para principiantes para continuar tu viaje de aprendizaje y dominar el lenguaje más versátil del mercado.