¿Cómo establecer encabezados personalizados en una llamada de Python requests?

PythonBeginner
Practicar Ahora

Introducción

En el mundo del desarrollo web y la recuperación de datos, comprender cómo establecer encabezados personalizados en las solicitudes de Python es una habilidad crucial. Este tutorial te guiará a través del proceso de agregar encabezados personalizados a tus solicitudes de Python, desbloqueando una amplia gama de posibilidades para el web scraping, las interacciones con API y mucho más.

Los encabezados personalizados te permiten controlar cómo tus solicitudes son procesadas por los servidores web y las API. Pueden ayudarte a autenticar solicitudes, especificar tipos de contenido, gestionar el almacenamiento en caché e incluso imitar el comportamiento del navegador. Al final de este tutorial, tendrás el conocimiento práctico para personalizar tus solicitudes HTTP y satisfacer requisitos específicos.

Comprensión de los Encabezados HTTP y la Biblioteca Requests

Antes de comenzar a escribir código, comprendamos qué son los encabezados HTTP y por qué son importantes.

¿Qué son los Encabezados HTTP?

Los encabezados HTTP son pares clave-valor enviados en las solicitudes y respuestas entre clientes y servidores. Proporcionan información adicional sobre la solicitud o respuesta, como el tipo de contenido, las credenciales de autenticación o la información del cliente.

Por ejemplo, cuando visitas un sitio web, tu navegador incluye automáticamente encabezados como User-Agent (que identifica tu navegador), Accept (que especifica qué tipos de contenido puedes manejar) y más.

Instalación de la Biblioteca Requests

La biblioteca Python Requests simplifica el trabajo con solicitudes HTTP. Asegurémonos de que esté instalada en nuestro entorno:

  1. Abre una terminal en el WebIDE y ejecuta:
pip install requests

Deberías ver una salida que indica que requests se está instalando o ya está instalado:

Requirement already satisfied: requests in /usr/local/lib/python3.10/dist-packages (2.28.1)
...

Creando tu Primer Script de Python con Requests

Creemos un script de Python simple para probar la biblioteca requests:

  1. Haz clic en el icono del Explorador en la barra lateral izquierda del WebIDE
  2. Haz clic con el botón derecho en el explorador de archivos y selecciona "Nuevo Archivo"
  3. Nombra el archivo test_requests.py
  4. Agrega el siguiente código al archivo:
import requests

## Make a simple GET request to a test website
response = requests.get('https://httpbin.org/get')

## Print the response status code
print(f"Status Code: {response.status_code}")

## Print the response headers (what the server sent back)
print("\nResponse Headers:")
for header, value in response.headers.items():
    print(f"{header}: {value}")

## Print the response content
print("\nResponse Content:")
print(response.text[:300] + "...")  ## Showing just the first 300 characters
  1. Ejecuta el script abriendo una terminal y ejecutando:
python test_requests.py

Deberías ver una salida similar a:

Status Code: 200

Response Headers:
Date: Wed, 12 Apr 2023 10:15:23 GMT
Content-Type: application/json
Content-Length: 267
Server: gunicorn/19.9.0
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true

Response Content:
{
  "args": {},
  "headers": {
    "Accept": "*/*",
    "Accept-Encoding": "gzip, deflate",
    "Host": "httpbin.org",
    "User-Agent": "python-requests/2.28.1",
    "X-Amzn-Trace-Id": "Root=1-643..."
  },
  "origin": "123.45.67.89",
  "url": "https://httpbin.org/get"
}
...

Esta salida muestra:

  1. El servidor respondió con el código de estado 200 (Éxito)
  2. Los encabezados que el servidor envió de vuelta
  3. El contenido real de la respuesta (en formato JSON)

Observa que el servidor registra los encabezados que recibió de nosotros, incluido el encabezado User-Agent generado automáticamente que identifica nuestra solicitud como proveniente de la biblioteca Python requests.

En el siguiente paso, aprenderemos a personalizar estos encabezados para tener más control sobre nuestras solicitudes.

Estableciendo Encabezados Personalizados Básicos en las Solicitudes de Python

Ahora que entendemos qué son los encabezados HTTP y hemos probado la biblioteca requests, aprendamos a establecer encabezados personalizados en nuestras solicitudes.

¿Por qué establecer encabezados personalizados?

Hay varias razones para establecer encabezados personalizados:

  1. Autenticación: Muchas API requieren tokens de autenticación enviados en los encabezados
  2. User-Agent: Cambia cómo te identificas ante los sitios web
  3. Content-Type: Especifica el formato de los datos que estás enviando
  4. Accept: Indica qué tipos de contenido puedes manejar
  5. Custom Headers: Algunas API requieren encabezados personalizados específicos

Estableciendo Encabezados en las Solicitudes

Creemos un nuevo script de Python para practicar la configuración de encabezados personalizados:

  1. En el WebIDE, crea un nuevo archivo llamado custom_headers.py
  2. Agrega el siguiente código:
import requests

## Define the URL we'll make the request to
url = 'https://httpbin.org/headers'

## Define custom headers in a dictionary
custom_headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
    'X-Custom-Header': 'Hello World',
    'Accept-Language': 'en-US,en;q=0.9'
}

## Make the request with our custom headers
response = requests.get(url, headers=custom_headers)

## Print the status code
print(f"Status Code: {response.status_code}")

## Print the response content (which shows the headers the server received)
print("\nHeaders received by server:")
print(response.json())
  1. Ejecuta el script:
python custom_headers.py

Deberías ver una salida similar a:

Status Code: 200

Headers received by server:
{'headers': {'Accept': '*/*', 'Accept-Encoding': 'gzip, deflate', 'Accept-Language': 'en-US,en;q=0.9', 'Host': 'httpbin.org', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', 'X-Custom-Header': 'Hello World', 'X-Amzn-Trace-Id': 'Root=1-6430a123-abc123def456'}}

¿Qué está pasando?

En este script, nosotros:

  1. Creamos un diccionario llamado custom_headers que contiene tres encabezados:

    • User-Agent: Lo cambiamos del valor predeterminado de Python requests para imitar un navegador web
    • X-Custom-Header: Un encabezado completamente personalizado que inventamos
    • Accept-Language: Especifica los idiomas preferidos para el contenido
  2. Pasamos nuestros encabezados a requests.get() usando el parámetro headers

  3. La respuesta de httpbin.org/headers nos muestra exactamente qué encabezados se recibieron, confirmando que nuestros encabezados personalizados se enviaron correctamente

Modificando Encabezados para un Caso de Uso Específico

Creemos otro ejemplo donde pretendemos ser un dispositivo móvil. Esto puede ser útil al probar sitios web con diseño adaptable (mobile-responsive):

  1. Crea un nuevo archivo llamado mobile_headers.py
  2. Agrega el siguiente código:
import requests

url = 'https://httpbin.org/headers'

## Header to simulate an iPhone
mobile_headers = {
    'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.0 Mobile/15E148 Safari/604.1',
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8'
}

print("Making request with mobile device headers...")
response = requests.get(url, headers=mobile_headers)

## Print the response content
print(response.json())
  1. Ejecuta el script:
python mobile_headers.py

Deberías ver una salida similar a:

Making request with mobile device headers...
{'headers': {'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', 'Accept-Encoding': 'gzip, deflate', 'Host': 'httpbin.org', 'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.0 Mobile/15E148 Safari/604.1', 'X-Amzn-Trace-Id': 'Root=1-6430a456-abc123def456'}}

Esto muestra que estamos indicando con éxito al servidor que somos un iPhone al establecer un encabezado User-Agent específico.

Trabajando con Encabezados de Autenticación

Uno de los usos más comunes de los encabezados personalizados es para la autenticación con servicios web y API. Muchas API requieren que incluyas información de autenticación en los encabezados de tus solicitudes.

Comprensión de los Encabezados de Autenticación

Existen varios métodos de autenticación comunes:

  1. API Keys: Tokens simples incluidos en los encabezados o parámetros de URL
  2. Basic Authentication: Nombre de usuario y contraseña codificados en Base64
  3. Bearer Tokens: Utilizados en la autenticación OAuth y JWT
  4. Custom Authentication: Esquemas de autenticación propietarios

Exploremos cómo implementar estos métodos de autenticación con las solicitudes de Python.

Autenticación con API Key

Muchas API permiten el acceso utilizando API keys. Estas se incluyen típicamente en los encabezados o como parámetros de URL:

  1. Crea un nuevo archivo llamado api_key_auth.py
  2. Agrega el siguiente código:
import requests

url = 'https://httpbin.org/headers'

## Simulating an API key authentication
api_key = 'my_fake_api_key_12345'

## Add the API key to the headers
headers = {
    'X-API-Key': api_key,
    'User-Agent': 'My API Client/1.0'
}

## Make the request
response = requests.get(url, headers=headers)

## Print results
print(f"Status Code: {response.status_code}")
print("\nHeaders received by server:")
print(response.json())
  1. Ejecuta el script:
python api_key_auth.py

Deberías ver una salida similar a:

Status Code: 200

Headers received by server:
{'headers': {'Accept': '*/*', 'Accept-Encoding': 'gzip, deflate', 'Host': 'httpbin.org', 'User-Agent': 'My API Client/1.0', 'X-API-Key': 'my_fake_api_key_12345', 'X-Amzn-Trace-Id': 'Root=1-6430a789-abc123def456'}}

Esto confirma que hemos enviado con éxito una API key en el encabezado X-API-Key.

Basic Authentication

La autenticación básica implica enviar un nombre de usuario y una contraseña codificados en formato base64. La biblioteca Requests facilita esto:

  1. Crea un nuevo archivo llamado basic_auth.py
  2. Agrega el siguiente código:
import requests

## URL that requires basic authentication
url = 'https://httpbin.org/basic-auth/user/pass'

## Method 1: Using the auth parameter (recommended)
print("Method 1: Using the auth parameter")
response = requests.get(url, auth=('user', 'pass'))
print(f"Status Code: {response.status_code}")
print(response.json())

## Method 2: Setting the Authorization header manually
print("\nMethod 2: Setting the Authorization header manually")
import base64

## Create the basic auth string: "username:password" encoded in base64
auth_string = base64.b64encode('user:pass'.encode('utf-8')).decode('utf-8')
headers = {
    'Authorization': f'Basic {auth_string}'
}

response = requests.get(url, headers=headers)
print(f"Status Code: {response.status_code}")
print(response.json())
  1. Ejecuta el script:
python basic_auth.py

Deberías ver una salida similar a:

Method 1: Using the auth parameter
Status Code: 200
{'authenticated': True, 'user': 'user'}

Method 2: Setting the Authorization header manually
Status Code: 200
{'authenticated': True, 'user': 'user'}

Ambos métodos se autenticaron con éxito con el servicio:

  • El Método 1 utiliza el parámetro auth integrado, que es más conveniente
  • El Método 2 muestra cómo funciona la autenticación básica "bajo el capó" creando manualmente el encabezado Authorization

Autenticación con Bearer Token

La autenticación con Bearer token se utiliza comúnmente en sistemas basados en OAuth 2.0 y JWT:

  1. Crea un nuevo archivo llamado bearer_auth.py
  2. Agrega el siguiente código:
import requests

url = 'https://httpbin.org/headers'

## Simulate a bearer token (in a real app this would come from an OAuth process)
bearer_token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIn0.Q6CM1qIQkXA_DqyJq9MI0-mnRRCRR3c0SIM-Nul5MZs'

## Add the Authorization header with the Bearer token
headers = {
    'Authorization': f'Bearer {bearer_token}'
}

## Make the request
response = requests.get(url, headers=headers)

## Print results
print(f"Status Code: {response.status_code}")
print("\nHeaders received by server:")
print(response.json())
  1. Ejecuta el script:
python bearer_auth.py

Deberías ver una salida similar a:

Status Code: 200

Headers received by server:
{'headers': {'Accept': '*/*', 'Accept-Encoding': 'gzip, deflate', 'Authorization': 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIn0.Q6CM1qIQkXA_DqyJq9MI0-mnRRCRR3c0SIM-Nul5MZs', 'Host': 'httpbin.org', 'X-Amzn-Trace-Id': 'Root=1-6430a901-abc123def456'}}

Esto muestra una solicitud exitosa con un Bearer token incluido en el encabezado Authorization.

Los Bearer tokens se obtienen típicamente después de un proceso de autenticación exitoso con un servidor OAuth 2.0, pero en este ejemplo, estamos utilizando un token de muestra con fines de demostración.

Aplicaciones Prácticas y Mejores Prácticas

Ahora que has aprendido a establecer varios tipos de encabezados personalizados, exploremos algunas aplicaciones prácticas y las mejores prácticas para trabajar con encabezados en escenarios del mundo real.

Envío y Recepción de Datos JSON

Al trabajar con API modernas, JSON es el formato de datos más común. Veamos cómo establecer correctamente los encabezados para las solicitudes JSON:

  1. Crea un nuevo archivo llamado json_requests.py
  2. Agrega el siguiente código:
import requests
import json

url = 'https://httpbin.org/post'  ## This endpoint accepts POST requests

## Data to send
data = {
    'name': 'John Doe',
    'email': 'john@example.com',
    'message': 'Hello, world!'
}

## Set appropriate headers for JSON
headers = {
    'Content-Type': 'application/json',
    'Accept': 'application/json'
}

## Method 1: Using the json parameter (recommended)
print("Method 1: Using the json parameter")
response = requests.post(url, json=data, headers=headers)
print(f"Status Code: {response.status_code}")
print(response.json()['headers'])  ## Show the headers received
print(f"\nData sent (as received by server): {response.json()['json']}")

## Method 2: Manually converting to JSON
print("\nMethod 2: Manually converting to JSON")
json_data = json.dumps(data)
response = requests.post(url, data=json_data, headers=headers)
print(f"Status Code: {response.status_code}")
print(response.json()['headers'])  ## Show the headers received
print(f"\nData sent (as received by server): {response.json()['json']}")
  1. Ejecuta el script:
python json_requests.py

Deberías ver una salida similar a:

Method 1: Using the json parameter
Status Code: 200
{'Accept': 'application/json', 'Accept-Encoding': 'gzip, deflate', 'Content-Length': '72', 'Content-Type': 'application/json', 'Host': 'httpbin.org', 'X-Amzn-Trace-Id': 'Root=1-6430ab12-abc123def456'}

Data sent (as received by server): {'name': 'John Doe', 'email': 'john@example.com', 'message': 'Hello, world!'}

Method 2: Manually converting to JSON
Status Code: 200
{'Accept': 'application/json', 'Accept-Encoding': 'gzip, deflate', 'Content-Length': '72', 'Content-Type': 'application/json', 'Host': 'httpbin.org', 'X-Amzn-Trace-Id': 'Root=1-6430ab13-abc123def456'}

Data sent (as received by server): {'name': 'John Doe', 'email': 'john@example.com', 'message': 'Hello, world!'}

Ten en cuenta que ambos métodos funcionan, pero el Método 1 es más conveniente porque la biblioteca Requests maneja la conversión JSON por ti.

Creación de una Sesión Reutilizable con Encabezados Predeterminados

Si necesitas hacer múltiples solicitudes con los mismos encabezados, usar un objeto Session puede ahorrar tiempo y hacer que tu código sea más limpio:

  1. Crea un nuevo archivo llamado session_headers.py
  2. Agrega el siguiente código:
import requests

## Create a session object
session = requests.Session()

## Set default headers for all requests made with this session
session.headers.update({
    'User-Agent': 'MyCustomApp/1.0',
    'Accept-Language': 'en-US,en;q=0.9',
    'X-API-Key': 'my_session_api_key'
})

## Make a request using the session - it will include our default headers
print("First request with session:")
response = session.get('https://httpbin.org/headers')
print(response.json())

## Add a custom header just for this request
print("\nSecond request with additional header:")
response = session.get('https://httpbin.org/headers',
                      headers={'X-Custom-Header': 'Just for this request'})
print(response.json())

## Original headers remain unchanged for future requests
print("\nThird request (original headers only):")
response = session.get('https://httpbin.org/headers')
print(response.json())
  1. Ejecuta el script:
python session_headers.py

Deberías ver una salida similar a:

First request with session:
{'headers': {'Accept': '*/*', 'Accept-Encoding': 'gzip, deflate', 'Accept-Language': 'en-US,en;q=0.9', 'Host': 'httpbin.org', 'User-Agent': 'MyCustomApp/1.0', 'X-API-Key': 'my_session_api_key', 'X-Amzn-Trace-Id': 'Root=1-6430ab45-abc123def456'}}

Second request with additional header:
{'headers': {'Accept': '*/*', 'Accept-Encoding': 'gzip, deflate', 'Accept-Language': 'en-US,en;q=0.9', 'Host': 'httpbin.org', 'User-Agent': 'MyCustomApp/1.0', 'X-API-Key': 'my_session_api_key', 'X-Custom-Header': 'Just for this request', 'X-Amzn-Trace-Id': 'Root=1-6430ab46-abc123def456'}}

Third request (original headers only):
{'headers': {'Accept': '*/*', 'Accept-Encoding': 'gzip, deflate', 'Accept-Language': 'en-US,en;q=0.9', 'Host': 'httpbin.org', 'User-Agent': 'MyCustomApp/1.0', 'X-API-Key': 'my_session_api_key', 'X-Amzn-Trace-Id': 'Root=1-6430ab47-abc123def456'}}

Usar sesiones es una mejor práctica por varias razones:

  1. Rendimiento mejorado (agrupación de conexiones)
  2. Encabezados consistentes en todas las solicitudes
  3. Manejo automático de cookies
  4. Capacidad de agregar personalización por solicitud cuando sea necesario

Mejores Prácticas para Trabajar con Encabezados

Para concluir, aquí hay algunas mejores prácticas a seguir al trabajar con encabezados HTTP:

  1. Usa Objetos Session para múltiples solicitudes al mismo dominio
  2. Establece los Encabezados Content-Type correctamente para los datos que estás enviando
  3. Maneja la Autenticación Correctamente - usa la autenticación integrada cuando sea posible
  4. Mantén la Información Sensible Segura - no codifiques API keys o tokens de forma estática
  5. Sigue la Documentación de la API cuidadosamente para los encabezados requeridos

Aquí hay un ejemplo final que demuestra estas mejores prácticas:

  1. Crea un nuevo archivo llamado best_practices.py
  2. Agrega el siguiente código:
import requests
import os

## In a real application, get these from environment variables or a secure configuration
## For this example, we're keeping it simple
API_KEY = os.environ.get('API_KEY', 'default_api_key')
BASE_URL = 'https://httpbin.org'

def create_api_client():
    """Create a reusable session with default headers."""
    session = requests.Session()

    ## Set common headers
    session.headers.update({
        'User-Agent': 'MyApp/1.0',
        'X-API-Key': API_KEY,
        'Accept': 'application/json'
    })

    return session

def get_data(client, endpoint):
    """Make a GET request to the specified endpoint."""
    url = f"{BASE_URL}/{endpoint}"
    response = client.get(url)
    return response.json()

def post_data(client, endpoint, data):
    """Make a POST request with JSON data."""
    url = f"{BASE_URL}/{endpoint}"
    response = client.post(url, json=data)
    return response.json()

## Usage example
def main():
    ## Create the API client
    client = create_api_client()

    ## GET request example
    print("Making GET request...")
    get_response = get_data(client, 'headers')
    print(f"Headers sent: {get_response['headers']}")

    ## POST request example
    print("\nMaking POST request...")
    data = {'name': 'John', 'age': 30}
    post_response = post_data(client, 'post', data)
    print(f"Data received by server: {post_response['json']}")

if __name__ == '__main__':
    main()
  1. Ejecuta el script:
python best_practices.py

Deberías ver una salida similar a:

Making GET request...
Headers sent: {'Accept': 'application/json', 'Accept-Encoding': 'gzip, deflate', 'Host': 'httpbin.org', 'User-Agent': 'MyApp/1.0', 'X-API-Key': 'default_api_key', 'X-Amzn-Trace-Id': 'Root=1-6430ab78-abc123def456'}

Making POST request...
Data received by server: {'name': 'John', 'age': 30}

Este ejemplo demuestra un enfoque estructurado para realizar solicitudes HTTP con encabezados personalizados, siguiendo las mejores prácticas como la creación de sesiones reutilizables, la organización del código en funciones y la evitación de información sensible codificada de forma estática.

Resumen

En este tutorial, has aprendido a trabajar con encabezados personalizados en las solicitudes de Python, lo cual es una habilidad esencial para una comunicación web efectiva y la integración de API.

Ahora entiendes:

  • Qué son los encabezados HTTP y por qué son importantes para las solicitudes web
  • Cómo establecer encabezados personalizados para solicitudes individuales
  • Varios métodos de autenticación utilizando encabezados (API keys, Basic auth, Bearer tokens)
  • Cómo trabajar correctamente con datos JSON y encabezados de tipo de contenido
  • Las mejores prácticas para gestionar encabezados con objetos de sesión

Estas habilidades te permitirán interactuar con cualquier API web de manera más efectiva, acceder a recursos protegidos, controlar cómo se procesan tus solicitudes y construir aplicaciones web más sofisticadas.

A medida que continúas desarrollando tus habilidades en Python, recuerda que comprender los conceptos básicos de HTTP, como los encabezados, los códigos de estado y los tipos de contenido, te ayudará a solucionar problemas e implementar funciones más avanzadas en tus aplicaciones web.