En esta guía completa, aprenderás:
- Qué es
requests, cómo instalarlo y por qué es la biblioteca cliente HTTP de Python más popular. - Cómo usarlo con diferentes métodos HTTP.
- Qué ofrece para manejar las respuestas del servidor.
- Qué personalizaciones de solicitudes admite.
- Los escenarios avanzados cubiertos por la biblioteca Python
requests
¡Comencemos!
Introducción a la Biblioteca Requests
Descubre qué es Requests, cómo instalarlo, cuándo usarlo y qué ofrece.
Definición
Requests es una biblioteca HTTP elegante y sencilla para Python. En detalle, proporciona una API intuitiva para realizar solicitudes HTTP y manejar respuestas de manera fácil y legible. Con más de 50k estrellas en GitHub y más de 500M de descargas mensuales, Requests es uno de los clientes HTTP más populares en Python.
Algunas de las características clave de esta biblioteca incluyen una API completa que cubre todos los métodos HTTP, manejo de respuestas, personalización de solicitudes, autenticación, gestión de certificados SSL y más. Además, el módulo Python Requests admite HTTP/1.1 de forma nativa. Ten en cuenta que si necesitas soporte para HTTP/2 (o HTTP/3), considera usar la biblioteca httpx (instalable con httpx[http2]) o requests-h2.
Configuración
Nota: A partir de la versión 2.32.5 (2026-08-18), Requests incluye correcciones de seguridad importantes (p. ej., CVE-2024-47081), revierte el caché problemático de SSLContext introducido en versiones anteriores y elimina el soporte para Python 3.8. Estos cambios afectan la configuración de SSL, la validación de hosts y las versiones de Python compatibles.
La forma más sencilla y recomendada de instalar Requests es mediante pip. En particular, el paquete pip asociado a la biblioteca Requests es requests. Por lo tanto, puedes instalar el cliente HTTP con el siguiente comando:
pip install requests
Para usar requests en tu script de Python, impórtalo con la siguiente línea:
import requests
¡Excelente! El paquete Requests ya está instalado y listo para usarse.
Casos de Uso
Los principales casos de uso de la biblioteca Python requests incluyen:
- Realizar solicitudes HTTP a servidores web: Recupera datos de servidores web enviando solicitudes GET.
- Consumir APIs: Envía solicitudes a endpoints de API y maneja sus respuestas, interactuando con diversos servicios web y accediendo a sus datos.
- Scraping web: Obtén documentos HTML asociados a páginas web, que luego pueden parsearse usando bibliotecas como
BeautifulSouppara extraer información específica. Aprende más en nuestra guía de scraping web con Python. - Probar aplicaciones web: Simula solicitudes HTTP y verifica las respuestas, automatizando el proceso de pruebas y garantizando el correcto funcionamiento de los servicios web.
- Descargar archivos: Recupera archivos de servidores web, como imágenes, documentos u otros archivos multimedia, enviando solicitudes HTTP
GETa las URLs correspondientes.
Métodos
Echa un vistazo a los métodos públicos expuestos por la biblioteca requests en la siguiente tabla:
| Método | Descripción |
requests.request() |
Envía una solicitud HTTP personalizada con el método especificado a la URL indicada |
requests.get() |
Envía una solicitud GET a la URL especificada |
requests.post() |
Envía una solicitud POST a la URL especificada |
requests.put() |
Envía una solicitud PUT a la URL especificada |
requests.patch() |
Envía una solicitud PATCH a la URL especificada |
requests.delete() |
Envía una solicitud DELETE a la URL especificada |
requests.head() |
Envía una solicitud HEAD a la URL especificada |
Como puedes ver, estos cubren los métodos de solicitud HTTP más útiles. Obtén más información sobre cómo usarlos en la documentación oficial de la API.
¡Es hora de verlos en acción!
Métodos HTTP
Observa la biblioteca Python requests en acción al trabajar con los métodos GET, POST, PUT, DELETE y HEAD en HTTP.
GET
En HTTP, el método GET se utiliza para solicitar un recurso específico de un servidor. Así es como puedes realizar una solicitud HTTP GET con requests.get():
import requests
# enviar una solicitud GET a la URL especificada
response = requests.get('https://api.example.com/data')
De igual manera, puedes lograr el mismo resultado con requests.request() como se muestra a continuación:
import requests
response = requests.request('GET', 'https://api.example.com/data')
En este caso, debes especificar manualmente el método HTTP a usar con una variable de cadena adicional.
POST
El método HTTP POST se utiliza para enviar datos a un servidor para su posterior procesamiento. Así es como se realiza una solicitud POST con requests.post():
import requests
# datos a enviar en la solicitud POST
product = {
'name': 'Limitor 500',
'description': 'The Limitor 500 is a high-performance electronic device designed to regulate power consumption in industrial settings. It offers advanced features such as real-time monitoring, adjustable settings, and remote access for efficient energy management.',
'price': 199.99,
'manufacturer': 'TechCorp Inc.',
'category': 'Electronics',
'availability': 'In Stock'
}
# enviar una solicitud POST a la URL especificada
response = requests.post('https://api.example.com/product', data=product)
En comparación con una solicitud GET, esta vez también debes especificar los datos a enviar al servidor mediante la opción data. requests añadirá estos datos al cuerpo de la solicitud HTTP.
Para cuerpos JSON, pasa tu objeto de datos a la opción json en lugar de data:
response = requests.post('https://api.example.com/product', json=product)
Considera leer nuestra guía sobre parseo de datos json con Python.
De manera equivalente, puedes realizar la misma solicitud con request.request() de la siguiente forma:
import requests
product = {
'name': 'Limitor 500',
'description': 'The Limitor 500 is a high-performance electronic device designed to regulate power consumption in industrial settings. It offers advanced features such as real-time monitoring, adjustable settings, and remote access for efficient energy management.',
'price': 199.99,
'manufacturer': 'TechCorp Inc.',
'category': 'Electronics',
'availability': 'In Stock'
}
response = requests.request('POST', 'https://api.example.com/product', data=product)
PUT
El método PUT se utiliza para actualizar o reemplazar un recurso en el servidor. Enviar una solicitud PUT con el módulo Python requests es sencillo y sigue un patrón similar al de las solicitudes POST. Lo que cambia es que el método a usar es requests.put(). Además, la cadena del método HTTP en requests.request() será 'PUT'.
PATCH
El método PATCH se utiliza para aplicar modificaciones parciales a un recurso en línea. Al igual que con las solicitudes PUT, enviar solicitudes PATCH en la biblioteca Python requests es similar a las solicitudes POST. Lo que cambia es que el método a emplear es requests.patch() y la cadena del método HTTP en requests.request() es 'PATCH'.
DELETE
El método DELETE se utiliza para eliminar un recurso identificado por una URI determinada. Así es como se realiza una solicitud HTTP DELETE en requests usando el método delete():
import requests
# enviar una solicitud DELETE para el producto con id = 75
response = requests.delete('https://api.example.com/products/75')
De manera equivalente, puedes realizar una solicitud DELETE con requests.request():
import requests
response = requests.request('DELETE', 'https://api.example.com/products/75')
HEAD
El método HEAD es similar a GET, pero solo solicita las cabeceras de la respuesta, sin el contenido del cuerpo. Por lo tanto, la respuesta devuelta por el servidor para una solicitud HEAD será equivalente a la de una solicitud GET, pero sin datos en el cuerpo.
Usa requests.head() para realizar una solicitud HTTP HEAD en Python:
import requests
# enviar una solicitud HEAD a la URL especificada
response = requests.head('https://api.example.com/resource')
De la misma manera, puedes realizar una solicitud HEAD con requests.request():
import requests
response = requests.request('HEAD', 'https://api.example.com/resource')
Desglose de un Objeto de Respuesta de Requests
Ahora que sabes cómo realizar solicitudes HTTP con requests, es momento de ver cómo trabajar con los objetos de respuesta.
Objeto de Respuesta
Después de realizar una solicitud HTTP, requests recibirá la respuesta del servidor y la mapeará en un objeto especial Response.
Observa el siguiente ejemplo de Python con requests:
import requests
response = requests.get('http://lumtest.com/myip.json')
print(response)
Esto devolverá:
<Response [200]>
response es un objeto Response que expone algunos métodos y propiedades útiles. ¡Explora los más importantes en las siguientes secciones!
Advertencia: requests no siempre devuelve una respuesta. En caso de errores (p. ej., una URL inválida o errores de sintaxis), lanza una excepción RequestException. Protégete contra esta excepción con la siguiente lógica:
try:
response = requests.get('http://lumtest.com/myip.json')
# manejar la respuesta
except requests.exceptions.RequestException as e:
print('Ocurrió un error durante la solicitud:', e)
Códigos de Estado
En HTTP, los códigos de estado de respuesta son valores estandarizados devueltos por el servidor para indicar el éxito, el fallo u otra condición de la solicitud. Estos códigos son fundamentales porque proporcionan retroalimentación inmediata sobre si la solicitud fue exitosa o no, y en caso negativo, qué salió mal.
Son especialmente útiles en el manejo de errores, permitiendo al cliente identificar y gestionar diferentes tipos de errores de forma adecuada. Por ejemplo, un código de estado 4xx indica un error del lado del cliente (p. ej., una solicitud inválida), mientras que un código 5xx indica un error del lado del servidor.
Verificar el código de estado es generalmente el primer paso para manejar una respuesta en Python usando la biblioteca requests. Después de realizar una solicitud, siempre debes comprobar el código de estado de la respuesta para determinar si fue exitosa. Accede al código de estado mediante el atributo status_code del objeto de respuesta:
response.status_code # 200
Dependiendo del código de estado recibido, debes usar instrucciones condicionales para manejar diferentes escenarios de forma apropiada:
import requests
response = requests.get('http://lumtest.com/myip.json')
# verificar si la solicitud fue exitosa (código de estado 200)
if response.status_code == 200:
print('¡Solicitud exitosa!')
# manejar la respuesta...
elif response.status_code == 404:
print('¡Recurso no encontrado!')
else:
print(f'La solicitud falló con el código de estado: {response.status_code}')
En la mayoría de los escenarios, solo necesitas distinguir entre una solicitud exitosa y una respuesta de error. requests simplifica ese proceso gracias a una sobrecarga personalizada de __bool()__. En concreto, puedes usar un objeto Response directamente en una expresión condicional. Esto evaluará True si el código de estado está entre 200 y 399, y False en caso contrario.
En otras palabras, es posible verificar el resultado exitoso de una solicitud con esta lógica:
if response:
print('¡Solicitud exitosa!')
# manejar la respuesta...
else:
print(f'La solicitud falló con el código de estado: {response.status_code}')
Cabeceras de Respuesta
Accede a las cabeceras de una respuesta del servidor mediante el atributo headers:
import requests
response = requests.get('http://lumtest.com/myip.json')
response_headers = response.headers
print(response_headers)
Esto imprimirá:
{'Server': 'nginx', 'Date': 'Thu, 09 May 2024 12:51:08 GMT', 'Content-Type': 'application/json; charset=utf-8', 'Content-Length': '279', 'Connection': 'keep-alive', 'Cache-Control': 'no-store', 'Access-Control-Allow-Origin': '*'}
Como puedes ver, response.headers devuelve un objeto similar a un diccionario. Esto significa que puedes acceder a los valores de las cabeceras por clave. Por ejemplo, si deseas acceder a la cabecera Content-Type de la respuesta, así es como puedes hacerlo:
response_headers['Content-Type'] # 'application/json; charset=utf-8'
Dado que la especificación HTTP define las cabeceras como insensibles a mayúsculas y minúsculas, requests te permite acceder a ellas sin preocuparte por su capitalización:
response_headers['content-type'] # 'application/json; charset=utf-8'
Contenido de la Respuesta
requests proporciona diferentes atributos y métodos para acceder al contenido de una respuesta:
response.content: Devuelve el contenido de la respuesta en bytes.response.text: Devuelve el contenido de la respuesta como una cadena en Unicode.response.json(): Devuelve el contenido codificado en JSON de la respuesta en un diccionario.
Véalos en acción en el siguiente ejemplo:
import requests
response = requests.get('http://lumtest.com/myip.json')
# acceder a la respuesta como bytes
response_bytes = response.content
print(type(response_bytes))
print(response_bytes)
print()
# obtener la respuesta como texto
response_text = response.text
print(type(response_text))
print(response_text)
print()
# obtener la respuesta como diccionario codificado en JSON
response_json = response.json()
print(type(response_json))
print(response_json)
print()
http://lumtest.com/myip.json es un endpoint especial que devuelve información sobre la IP del solicitante. El resultado del fragmento anterior será algo como:
<class 'bytes'>
b'{"ip":"45.85.135.110","country":"US","asn":{"asnum":62240,"org_name":"Clouvider Limited"},"geo":{"city":"Ashburn","region":"VA","region_name":"Virginia","postal_code":"20149","latitude":39.0469,"longitude":-77.4903,"tz":"America/New_York","lum_city":"ashburn","lum_region":"va"}}'
<class 'str'>
{"ip":"45.85.135.110","country":"US","asn":{"asnum":62240,"org_name":"Clouvider Limited"},"geo":{"city":"Ashburn","region":"VA","region_name":"Virginia","postal_code":"20149","latitude":39.0469,"longitude":-77.4903,"tz":"America/New_York","lum_city":"ashburn","lum_region":"va"}}
<class 'dict'>
{'ip': '45.85.135.110', 'country': 'US', 'asn': {'asnum': 62240, 'org_name': 'Clouvider Limited'}, 'geo': {'city': 'Ashburn', 'region': 'VA', 'region_name': 'Virginia', 'postal_code': '20149', 'latitude': 39.0469, 'longitude': -77.4903, 'tz': 'America/New_York', 'lum_city': 'ashburn', 'lum_region': 'va'}}
Observa los tres formatos de respuesta diferentes. Como diccionario, response.json() es especialmente útil porque simplifica el acceso a los datos:
response_json['country'] # 'US'
Para más información, consulta nuestra guía sobre cómo parsear JSON en Python.
Cookies de Respuesta
Aunque las cookies HTTP se definen mediante cabeceras, el objeto Response proporciona un atributo especial cookies para trabajar con ellas. Este devuelve un objeto http.cookiejar con las cookies que el servidor devolvió.
Observa el siguiente ejemplo que muestra cómo acceder a las cookies desde un objeto de respuesta en la biblioteca Python requests:
import requests
# definir las credenciales de inicio de sesión
credentials = {
'username': 'example_user',
'password': 'example_password'
}
# enviar una solicitud POST al endpoint de inicio de sesión
response = requests.post('https://www.example.com/login', data=credentials)
# acceder a las cookies establecidas por el servidor
cookies = response.cookies
# imprimir las cookies recibidas del servidor
for cookie in cookies:
print(cookie.name, ':', cookie.value)
El fragmento de ejemplo anterior puede producir algo como esto:
session_id : be400765483cf840dfbbd39
user_id : 7164
expires : Sat, 01 Jan 2026 14:30:00 GMT
Personalización de Solicitudes con la Biblioteca Python Requests
Las solicitudes HTTP a menudo implican parámetros de filtrado especiales y cabeceras personalizadas. Veamos cómo especificarlos en requests.
Parámetros de Cadena de Consulta
Los parámetros de consulta, también conocidos como parámetros de URL, son parámetros adicionales añadidos al final de una URL en una solicitud HTTP. Proporcionan información extra al servidor sobre la solicitud, generalmente sobre cómo filtrar datos y personalizar la respuesta.
Considera esta URL:
https://api.example.com/data?key1=value1&key2=value2
En este ejemplo, ?key1=value1&key2=value2 es la cadena de consulta, mientras que key1 y key2 son los parámetros de consulta.
Una cadena de consulta comienza con ? y consiste en pares clave-valor separados por un signo igual (=) y concatenados por &. Especificar esta cadena de consulta programáticamente en código Python no siempre es sencillo, especialmente cuando se trabaja con parámetros opcionales. Por eso requests ofrece la opción params:
import requests
# definir parámetros de consulta como un diccionario
params = {
'page': 1,
'limit': 10,
'category': 'electronics'
}
# enviar una solicitud GET a la siguiente URL:
# 'https://api.example.com/products?page=1&limit=10&category=electronics'
response = requests.get('https://api.example.com/products', params=params)
De manera equivalente, puedes pasar los parámetros a requests como una lista de tuplas:
import requests
# definir parámetros de consulta como una lista de tuplas
params = [
('page', '1'),
('limit', '10'),
('category', 'electronics')
]
response = requests.get('https://api.example.com/products', params=params)
O como una cadena de bytes:
import requests
# definir parámetros de consulta como una cadena de bytes
params = b'page=1&limit=10&category=electronics'
response = requests.get('https://api.example.com/products', params=params)
Cabeceras de Solicitud
Para personalizar las cabeceras en una solicitud HTTP en requests, pásalas como un diccionario a la opción headers. Por ejemplo, puedes establecer una cadena User-Agent personalizada en requests con:
import requests
# definir cabeceras personalizadas
custom_headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36',
# otras cabeceras...
}
# enviar una solicitud GET con cabeceras personalizadas
response = requests.get('https://api.example.com/data', headers=custom_headers)
Aprende más sobre User-Agent en requests.
Cookies de Solicitud
Aunque las cookies HTTP se envían al servidor mediante cabeceras, requests proporciona una opción dedicada cookies para personalizarlas. Úsala como en el siguiente ejemplo:
# definir cookies personalizadas
custom_cookies = {
'session_id': 'be400765483cf840dfbbd39',
'user_id': '7164'
}
# enviar una solicitud GET con cookies personalizadas
response = requests.get('https://www.example.com', cookies=custom_cookies)
Ten en cuenta que cookies acepta un diccionario o un objeto http.cookiejar.
Otras Configuraciones
request ofrece una API rica y hay muchas técnicas avanzadas disponibles. ¡Explora algunas de las más relevantes!
Configuración de Proxy
La integración de Proxy en requests te permite enrutar tus solicitudes HTTP a través de un servidor Proxy. Es un mecanismo poderoso para ocultar tu dirección IP, eludir limitadores de velocidad o acceder a contenido con restricciones geográficas.
Puedes integrar un servidor Proxy con la biblioteca Python requests usando la opción proxies:
import requests
# definir la configuración del proxy
proxy = {
'http': 'http://username:[email protected]:8080',
'https': 'https://username:[email protected]:8080'
}
# Realizar una solicitud usando el proxy
response = requests.get('https://www.example.com', proxies=proxy)
Para un tutorial completo, sigue nuestra guía sobre uso de Proxy con Python Requests.
Autenticación Básica
La autenticación HTTP, mejor conocida como “autenticación básica”, es un esquema de autenticación simple integrado en el protocolo HTTP. Implica enviar un nombre de usuario y contraseña codificados en formato Base64 en la cabecera Authorization.
Aunque podrías implementarlo configurando manualmente la cabecera Authorization, requests expone una opción dedicada auth para ello. Esta acepta una tupla con el nombre de usuario y la contraseña. Úsala para manejar la autenticación básica en la biblioteca Python requests:
import requests
# definir el nombre de usuario y contraseña para la autenticación básica
username = 'sample_username'
password = 'sample_password'
# enviar una solicitud GET con autenticación básica
response = requests.get('https://api.example.com/private/users', auth=(username, password))
Verificación de Certificados SSL
La verificación de certificados SSL es fundamental para garantizar una comunicación segura entre clientes y servidores a través de Internet. Al mismo tiempo, hay situaciones en las que confías en el servidor de destino y no necesitas aplicar la verificación.
En particular, al enrutar el tráfico HTTP a través de servidores Proxy, puedes encontrar errores relacionados con certificados SSL. En ese caso, es posible que necesites deshabilitar la verificación de certificados SSL. En requests, esto es posible mediante la opción verify:
import requests
# enviar una solicitud GET a un sitio web con la verificación de certificados SSL deshabilitada
response = requests.get('https://api.example.com/data', verify=False)
Tiempos de Espera
Por defecto, requests espera indefinidamente a que el servidor responda. Si el servidor experimenta una sobrecarga o hay una ralentización de la red, ese comportamiento puede convertirse en un problema.
Para evitar ralentizar tu aplicación mientras esperas una respuesta que quizás nunca llegue, requests tiene una opción timeout. Esta acepta un número entero o decimal que representa los segundos a esperar para una respuesta:
import requests
# tiempo de espera después de 2 segundos
response1 = requests.get("https://api.example.com/data", timeout=2)
Alternativamente, timeout acepta una tupla con dos elementos: tiempo de espera de conexión y tiempo de espera de lectura. Especifícalos como en el siguiente ejemplo:
import requests
# tiempo de espera de 2.5 segundos para conexiones y 4 segundos para leer la respuesta
response = requests.get("https://api.example.com/data", timeout=(2.5, 4))
Si la solicitud establece una conexión dentro del tiempo de espera de conexión especificado y recibe datos dentro del tiempo de espera de lectura, la respuesta se devolverá normalmente. De lo contrario, si la solicitud agota el tiempo de espera, se lanzará una excepción Timeout:
import requests
from requests.exceptions import Timeout
try:
response = requests.get("https://api.example.com/data", timeout=(2.5, 4))
except Timeout:
print("La solicitud agotó el tiempo de espera")
Por supuesto, aquí está la sección revisada sin guiones largos, manteniendo la concisión y consistencia con el estilo del artículo:
Consejo profesional: requests-h2, soporte HTTP/2 para usuarios de Requests
Aunque la biblioteca requests es popular por su facilidad de uso, solo admite HTTP/1.1 de forma predeterminada. Si necesitas soporte HTTP/2 manteniendo la API familiar al estilo requests, prueba requests-h2.
requests-h2 es una alternativa directa a requests que te permite enviar solicitudes HTTP/1.1 y HTTP/2. Está construida sobre requests y httpcore, es compatible con Python 3.7 y superior, y no requiere que actualices OpenSSL para usar HTTP/2.
Instala con pip:
pip install requests-h2
El uso es casi idéntico al de requests:
import requests_h2 as requests
# Enviar una solicitud HTTP/2 configurando http2=True
response = requests.get('https://www.google.com', http2=True)
print(response.status_code) # 200
print(response.version) # 'HTTP/2'
requests-h2 es una buena opción si deseas una forma sencilla de acceder a HTTP/2 para mejor rendimiento o soporte de API, con cambios mínimos en tu código existente. Simplemente cambia tu importación a requests_h2 y añade el parámetro http2=True.
Conclusión
En este artículo, exploraste la biblioteca requests, comprendiendo qué es, qué métodos tiene, cómo usarlos y más. Aprendiste que el módulo Python requests es una biblioteca HTTP útil y popular que cubre varios casos de uso.
El problema es que cualquier solicitud HTTP expone tu IP pública. Esto proporciona información sobre quién eres y dónde vives, lo cual no es bueno para tu privacidad. Hay varias formas de ocultar tu dirección IP, y la forma más efectiva de lograr mayor seguridad y privacidad es usar un servidor Proxy.
Bright Data controla los mejores servidores Proxy del mundo, sirviendo a empresas Fortune 500 y más de 20,000 clientes. Su oferta incluye una amplia gama de tipos de Proxy:
- Proxies de centro de datos – Más de 770,000 IPs de centros de datos.
- Proxies residenciales – Más de 150M de IPs residenciales en más de 195 países.
- Proxies ISP – Más de 700,000 IPs ISP.