Как установить пользовательские заголовки в вызове Python requests

PythonBeginner
Практиковаться сейчас

Введение

В мире веб-разработки и извлечения данных понимание того, как устанавливать пользовательские заголовки (custom headers) в Python запросах, является важным навыком. Этот учебник проведет вас через процесс добавления пользовательских заголовков в ваши Python запросы, открывая широкий спектр возможностей для веб-скрейпинга (web scraping), взаимодействия с API и многого другого.

Пользовательские заголовки позволяют вам контролировать, как ваши запросы обрабатываются веб-серверами и API. Они могут помочь вам аутентифицировать запросы, указывать типы контента, управлять кэшированием и даже имитировать поведение браузера. К концу этого учебника вы получите практические знания, необходимые для настройки ваших HTTP-запросов в соответствии с конкретными требованиями.

Понимание HTTP-заголовков и библиотеки Requests

Прежде чем мы начнем писать код, давайте разберемся, что такое HTTP-заголовки и почему они важны.

Что такое HTTP-заголовки?

HTTP-заголовки - это пары ключ-значение, отправляемые в запросах и ответах между клиентами и серверами. Они предоставляют дополнительную информацию о запросе или ответе, такую как тип контента, учетные данные аутентификации или информация о клиенте.

Например, когда вы посещаете веб-сайт, ваш браузер автоматически включает заголовки, такие как User-Agent (идентифицирующий ваш браузер), Accept (указывающий, какие типы контента вы можете обрабатывать) и другие.

Установка библиотеки Requests

Библиотека Python Requests упрощает работу с HTTP-запросами. Давайте убедимся, что она установлена в нашей среде:

  1. Откройте терминал в WebIDE и выполните:
pip install requests

Вы должны увидеть вывод, указывающий, что requests устанавливается или уже установлен:

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

Создание вашего первого Python-скрипта с использованием Requests

Давайте создадим простой Python-скрипт для тестирования библиотеки requests:

  1. Нажмите на значок Explorer на левой боковой панели WebIDE.
  2. Щелкните правой кнопкой мыши в проводнике файлов и выберите "New File" (Новый файл).
  3. Назовите файл test_requests.py.
  4. Добавьте следующий код в файл:
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. Запустите скрипт, открыв терминал и выполнив:
python test_requests.py

Вы должны увидеть вывод, похожий на:

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"
}
...

Этот вывод показывает:

  1. Сервер ответил кодом состояния 200 (Успешно)
  2. Заголовки, которые сервер отправил обратно
  3. Фактическое содержимое ответа (в формате JSON)

Обратите внимание, что сервер записывает заголовки, которые он получил от нас, включая автоматически сгенерированный заголовок User-Agent, который идентифицирует наш запрос как исходящий из библиотеки Python requests.

На следующем шаге мы узнаем, как настроить эти заголовки, чтобы иметь больше контроля над нашими запросами.

Установка базовых пользовательских заголовков в Python Requests

Теперь, когда мы понимаем, что такое HTTP-заголовки, и протестировали библиотеку requests, давайте узнаем, как устанавливать пользовательские заголовки в наших запросах.

Зачем устанавливать пользовательские заголовки?

Существует несколько причин для установки пользовательских заголовков:

  1. Аутентификация (Authentication): Многие API требуют токены аутентификации, отправляемые в заголовках.
  2. User-Agent: Изменение способа идентификации себя на веб-сайтах.
  3. Content-Type: Указание формата отправляемых данных.
  4. Accept: Указание типов контента, которые вы можете обрабатывать.
  5. Custom Headers: Некоторые API требуют определенные пользовательские заголовки.

Установка заголовков в Requests

Давайте создадим новый Python-скрипт, чтобы попрактиковаться в установке пользовательских заголовков:

  1. В WebIDE создайте новый файл с именем custom_headers.py.
  2. Добавьте следующий код:
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. Запустите скрипт:
python custom_headers.py

Вы должны увидеть вывод, похожий на:

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'}}

Что происходит?

В этом скрипте мы:

  1. Создали словарь с именем custom_headers, содержащий три заголовка:

    • User-Agent: Мы изменили его со значения по умолчанию Python requests, чтобы имитировать веб-браузер.
    • X-Custom-Header: Полностью пользовательский заголовок, который мы придумали.
    • Accept-Language: Указывает предпочтительные языки для контента.
  2. Передали наши заголовки в requests.get(), используя параметр headers.

  3. Ответ от httpbin.org/headers показывает нам, какие именно заголовки были получены, подтверждая, что наши пользовательские заголовки были успешно отправлены.

Изменение заголовков для конкретного варианта использования

Давайте создадим еще один пример, где мы притворяемся мобильным устройством. Это может быть полезно при тестировании веб-сайтов, адаптированных для мобильных устройств:

  1. Создайте новый файл с именем mobile_headers.py.
  2. Добавьте следующий код:
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. Запустите скрипт:
python mobile_headers.py

Вы должны увидеть вывод, похожий на:

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'}}

Это показывает, что мы успешно сообщаем серверу, что мы iPhone, установив определенный заголовок User-Agent.

Работа с заголовками аутентификации

Одним из наиболее распространенных применений пользовательских заголовков является аутентификация с веб-сервисами и API. Многие API требуют, чтобы вы включали информацию об аутентификации в заголовки ваших запросов.

Понимание заголовков аутентификации

Существует несколько распространенных методов аутентификации:

  1. API Keys: Простые токены, включенные в заголовки или параметры URL.
  2. Basic Authentication: Закодированное в формате Base64 имя пользователя и пароль.
  3. Bearer Tokens: Используются в аутентификации OAuth и JWT.
  4. Custom Authentication: Собственные схемы аутентификации.

Давайте рассмотрим, как реализовать эти методы аутентификации с помощью Python requests.

Аутентификация по API-ключу

Многие API разрешают доступ с использованием API-ключей. Они обычно включаются в заголовки или в качестве параметров URL:

  1. Создайте новый файл с именем api_key_auth.py.
  2. Добавьте следующий код:
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. Запустите скрипт:
python api_key_auth.py

Вы должны увидеть вывод, похожий на:

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'}}

Это подтверждает, что мы успешно отправили API-ключ в заголовке X-API-Key.

Basic Authentication

Basic Authentication предполагает отправку имени пользователя и пароля, закодированных в формате base64. Библиотека Requests упрощает это:

  1. Создайте новый файл с именем basic_auth.py.
  2. Добавьте следующий код:
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. Запустите скрипт:
python basic_auth.py

Вы должны увидеть вывод, похожий на:

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'}

Оба метода успешно прошли аутентификацию в сервисе:

  • Метод 1 использует встроенный параметр auth, что более удобно.
  • Метод 2 показывает, как работает Basic Authentication "под капотом", вручную создавая заголовок Authorization.

Bearer Token Authentication

Bearer token authentication обычно используется в системах на основе OAuth 2.0 и JWT:

  1. Создайте новый файл с именем bearer_auth.py.
  2. Добавьте следующий код:
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. Запустите скрипт:
python bearer_auth.py

Вы должны увидеть вывод, похожий на:

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'}}

Это показывает успешный запрос с токеном Bearer, включенным в заголовок Authorization.

Токены Bearer обычно получаются после успешного процесса аутентификации с сервером OAuth 2.0, но в этом примере мы используем образец токена для демонстрационных целей.

Практическое применение и лучшие практики

Теперь, когда вы узнали, как устанавливать различные типы пользовательских заголовков, давайте рассмотрим некоторые практические применения и лучшие практики работы с заголовками в реальных сценариях.

Отправка и получение данных JSON

При работе с современными API JSON является наиболее распространенным форматом данных. Давайте посмотрим, как правильно устанавливать заголовки для JSON-запросов:

  1. Создайте новый файл с именем json_requests.py.
  2. Добавьте следующий код:
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. Запустите скрипт:
python json_requests.py

Вы должны увидеть вывод, похожий на:

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!'}

Обратите внимание, что оба метода работают, но Метод 1 более удобен, потому что библиотека Requests обрабатывает преобразование JSON за вас.

Создание повторно используемой сессии с заголовками по умолчанию

Если вам нужно сделать несколько запросов с одними и теми же заголовками, использование объекта Session может сэкономить время и сделать ваш код чище:

  1. Создайте новый файл с именем session_headers.py.
  2. Добавьте следующий код:
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. Запустите скрипт:
python session_headers.py

Вы должны увидеть вывод, похожий на:

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'}}

Использование сессий является лучшей практикой по нескольким причинам:

  1. Повышенная производительность (объединение соединений).
  2. Согласованные заголовки во всех запросах.
  3. Автоматическая обработка файлов cookie.
  4. Возможность добавления настройки для каждого запроса при необходимости.

Лучшие практики работы с заголовками

В заключение, вот некоторые лучшие практики, которым следует следовать при работе с HTTP-заголовками:

  1. Используйте объекты Session для нескольких запросов к одному и тому же домену.
  2. Устанавливайте заголовки Content-Type правильно для отправляемых данных.
  3. Правильно обрабатывайте аутентификацию - используйте встроенную аутентификацию, когда это возможно.
  4. Сохраняйте конфиденциальную информацию в безопасности - не кодируйте API-ключи или токены жестко.
  5. Внимательно следуйте документации API для требуемых заголовков.

Вот окончательный пример, демонстрирующий эти лучшие практики:

  1. Создайте новый файл с именем best_practices.py.
  2. Добавьте следующий код:
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. Запустите скрипт:
python best_practices.py

Вы должны увидеть вывод, похожий на:

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}

Этот пример демонстрирует структурированный подход к выполнению HTTP-запросов с пользовательскими заголовками, следуя лучшим практикам, таким как создание повторно используемых сессий, организация кода в функции и избежание жесткого кодирования конфиденциальной информации.

Резюме

В этом руководстве вы узнали, как работать с пользовательскими заголовками в Python requests, что является важным навыком для эффективной веб-коммуникации и интеграции API.

Теперь вы понимаете:

  • Что такое HTTP-заголовки и почему они важны для веб-запросов.
  • Как устанавливать пользовательские заголовки для отдельных запросов.
  • Различные методы аутентификации с использованием заголовков (API keys, Basic auth, Bearer tokens).
  • Как правильно работать с данными JSON и заголовками content type.
  • Лучшие практики управления заголовками с помощью объектов session.

Эти навыки позволят вам более эффективно взаимодействовать с любым веб-API, получать доступ к защищенным ресурсам, контролировать обработку ваших запросов и создавать более сложные веб-приложения.

По мере развития ваших навыков Python помните, что понимание основ HTTP, таких как заголовки, коды состояния и типы контента, поможет вам устранять неполадки и реализовывать более продвинутые функции в ваших веб-приложениях.