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.