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 texto
  • json(): Contenido parseado como JSON
  • headers: Encabezados de la respuesta
  • cookies: 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 excepciones
  • requests.exceptions.ConnectionError: Error de conexión de red
  • requests.exceptions.Timeout: Tiempo límite excedido
  • requests.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:

🚀 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.