Requests.Session: примеры (PYTHON)

Использование requests.Session для HTTP-запросов
Раздел: HTTP-клиенты, Сессии
requests.Session: requests.Session

Объект Session для HTTP-запросов

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

Основные аргументы, которые можно передать при создании экземпляра сессии, соответствуют параметрам для отдельных запросов и могут быть установлены как атрибуты объекта для последующего использования по умолчанию:

  • headers - заголовки HTTP, используемые по умолчанию для всех запросов сессии (словарь).
  • cookies - объект кук для отправки с запросами (словарь или RequestsCookieJar).
  • auth - параметры аутентификации, например, кортеж ('login', 'password') для HTTP Basic Auth.
  • proxies - настройки прокси-серверов (словарь).
  • hooks - callback-функции, вызываемые при получении ответа (словарь).
  • params - query string параметры по умолчанию (словарь).
  • verify - проверка SSL-сертификата (путь к CA_BUNDLE или булево значение).
  • cert - путь к файлу клиентского сертификата или кортеж (cert, key).
  • adapters - адаптеры для обработки запросов к разным схемам URL.
  • stream - режим потоковой загрузки ответа (по умолчанию False).
  • trust_env - использование параметров из переменных окружения (по умолчанию True).
  • max_redirects - максимальное количество разрешенных перенаправлений.

Методы сессии (get, post, put, delete и т.д.) возвращают объект requests.Response, содержащий ответ сервера, атрибуты (status_code, headers, cookies, text, content, json()) и методы для работы с ним.

Базовые примеры использования

Пример создания сессии и выполнения GET-запроса с сохранением кук:

import requests

# Создание сессии
session = requests.Session()

# Установка общих заголовков
session.headers.update({'User-Agent': 'MyApp/1.0'})

# Выполнение запроса
response = session.get('https://httpbin.org/cookies/set/sessioncookie/123456789')
print(f'Статус код: {response.status_code}')
print(f'Куки в сессии: {session.cookies.get_dict()}')
Статус код: 200
Куки в сессии: {'sessioncookie': '123456789'}

Пример использования параметров аутентификации:

session = requests.Session()
session.auth = ('username', 'password')
response = session.get('https://httpbin.org/basic-auth/username/password')
print(response.json())
{'authenticated': True, 'user': 'username'}

Пример с установкой времени ожидания (timeout) для всех запросов сессии:

from requests.adapters import HTTPAdapter

session = requests.Session()
adapter = HTTPAdapter(timeout=2.5)
session.mount('https://', adapter)
session.mount('http://', adapter)

try:
    response = session.get('https://httpbin.org/delay/5')
except requests.exceptions.Timeout:
    print('Запрос превысил время ожидания.')
Запрос превысил время ожидания.

Похожие возможности в Python

Библиотека httpx предлагает аналогичный клиент с поддержкой HTTP/2 и асинхронных запросов. Её AsyncClient может быть предпочтительнее для асинхронных приложений.

import httpx

# Синхронный клиент, похожий на requests.Session
with httpx.Client() as client:
    response = client.get('https://httpbin.org/get')
    print(response.status_code)

# Асинхронный клиент
import asyncio
async def main():
    async with httpx.AsyncClient() as client:
        response = await client.get('https://httpbin.org/get')
        print(response.status_code)
# asyncio.run(main())

aiohttp.ClientSession - асинхронная альтернатива для высокопроизводительных приложений. Требует использования async/await.

urllib.request.OpenerDirector из стандартной библиотеки предоставляет схожие возможности для управления куки и заголовками, но имеет менее удобный API по сравнению с requests.

Выбор зависит от проекта: requests.Session подходит для большинства синхронных задач благодаря простоте, httpx - для современных проектов с возможным переходом на асинхронность, aiohttp - для строго асинхронных высоконагруженных приложений.

Аналоги в других языках программирования

JavaScript (Node.js): Библиотека axios или встроенный модуль http/https с сохранением кук вручную. Axios предоставляет наиболее близкий по удобству интерфейс.

// Использование axios
const axios = require('axios');

// Создание экземпляра с настройками
const instance = axios.create({
  baseURL: 'https://api.example.com',
  timeout: 1000,
  headers: {'X-Custom-Header': 'foobar'}
});

instance.get('/user')
  .then(response => console.log(response.data))
  .catch(error => console.error(error));

PHP: Использование cURL с сохранением дескриптора или библиотеки типа Guzzle.

<?
$ch = curl_init();
curl_setopt($ch, CURLOPT_COOKIEJAR, '/tmp/cookies.txt');
curl_setopt($ch, CURLOPT_URL, 'https://httpbin.org/cookies/set/test/php');
curl_exec($ch);
curl_close($ch);
?>

Java: HttpClient, начиная с Java 11, поддерживает управление сессиями и куками через CookieHandler.

HttpClient client = HttpClient.newBuilder()
        .cookieHandler(new CookieManager())
        .build();
HttpRequest request = HttpRequest.newBuilder()
        .uri(URI.create("https://httpbin.org/cookies/set/test/java"))
        .build();
client.sendAsync(request, HttpResponse.BodyHandlers.ofString());

C#: Класс HttpClient предназначен для многократного использования и по умолчанию управляет соединениями через ServicePointManager.

using var client = new HttpClient();
client.DefaultRequestHeaders.Add("User-Agent", "MyApp");
var response = await client.GetStringAsync("https://httpbin.org/get");
Console.WriteLine(response);

Golang: Стандартный пакет net/http предоставляет клиент, который автоматически управляет куками при использовании одного экземпляра.

client := &http.Client{}
req, _ := http.NewRequest("GET", "https://httpbin.org/cookies", nil)
resp, _ := client.Do(req)
defer resp.Body.Close()

Отличие Python-решения часто заключается в более лаконичном и «питоническом» синтаксисе библиотеки requests.

Распространенные ошибки

Ошибка повторного использования сессии после закрытия соединения.

session = requests.Session()
response = session.get('https://httpbin.org/get')
session.close()
# Попытка использовать сессию после закрытия вызовет предупреждение или ошибку.
try:
    response2 = session.get('https://httpbin.org/get')
except Exception as e:
    print(f'Ошибка: {type(e).__name__}')
Ошибка: AttributeError

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

session = requests.Session()
# Этот заголовок отправится только в этом запросе
response = session.get('https://httpbin.org/headers', headers={'X-Test': 'Value1'})
# А этот запрос отправится без заголовка X-Test
response2 = session.get('https://httpbin.org/headers')
print('Первый запрос:', response.request.headers.get('X-Test'))
print('Второй запрос:', response2.request.headers.get('X-Test'))
Первый запрос: Value1
Второй запрос: None

Использование сессии для потоковой загрузки без последующего закрытия ответа может привести к утечкам соединений.

session = requests.Session()
# При stream=True необходимо явно закрывать ответ
resp = session.get('https://httpbin.org/stream/10', stream=True)
# Обязательно нужно прочитать или закрыть ответ
resp.close()  # Важно!

Попытка сериализации или кеширования объекта сессии, который не предназначен для этого.

Изменения в последних версиях

В версии 2.28.0 библиотеки requests была улучшена поддержка типа JSONDecoder для параметра json в методах запросов. Для Session это означает возможность более гибкой обработки JSON.

Начиная с версии 2.0.0, библиотека официально отказалась от поддержки Python 2.7 и 3.5, что позволило использовать современные возможности языка в кодовой базе, но это не привело к кардинальным изменениям в публичном API класса Session.

В более ранних версиях были внесены изменения, связанные с безопасностью, такие как строгая проверка доменных имен в SSL-сертификатах по умолчанию. Рекомендуется всегда использовать актуальную версию библиотеки.

Расширенные и специальные примеры

Использование адаптеров для настройки количества повторных попыток и пула соединений.

Пример python
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry

session = requests.Session()

# Стратегия повторных попыток
retry_strategy = Retry(
    total=3,
    backoff_factor=1,
    status_forcelist=[429, 500, 502, 503, 504],
)

adapter = HTTPAdapter(max_retries=retry_strategy, pool_connections=10, pool_maxsize=100)
session.mount('https://', adapter)
session.mount('http://', adapter)

# Запросы будут автоматически повторяться при указанных ошибках
response = session.get('https://httpbin.org/status/500')
print(f'Финальный статус после повторов: {response.status_code}')

Использование хуков для глобальной обработки ответов или запросов.

Пример python
def log_response_info(r, *args, **kwargs):
    print(f'URL: {r.url}, Время: {r.elapsed.total_seconds():.2f}с')

session = requests.Session()
session.hooks['response'] = [log_response_info]

# Для каждого ответа через эту сессию будет вызван хук
session.get('https://httpbin.org/delay/1')
session.post('https://httpbin.org/post', data={'key': 'value'})
URL: https://httpbin.org/delay/1, Время: 1.02с
URL: https://httpbin.org/post, Время: 0.75с

Монтирование кастомных адаптеров для разных префиксов URL.

Пример python
class CustomAdapter(HTTPAdapter):
    def send(self, request, **kwargs):
        # Кастомная логика перед отправкой
        request.headers['X-Custom-Adapter'] = 'Used'
        return super().send(request, **kwargs)

session = requests.Session()

# Использовать кастомный адаптер только для api.example.com
custom_adapter = CustomAdapter()
session.mount('https://api.example.com', custom_adapter)

# Для других хостов будет использоваться адаптер по умолчанию
session.get('https://api.example.com/v1/data')
session.get('https://httpbin.org/get')

Имитация состояния браузера с сохранением и отправкой кук между запросами.

Пример python
session = requests.Session()

# Первый запрос устанавливает куки
session.get('https://httpbin.org/cookies/set/initial/1')

# Второй запрос отправляет установленные куки автоматически
resp = session.get('https://httpbin.org/cookies')
print('Куки, видимые сервером во втором запросе:')
print(resp.json())
Куки, видимые сервером во втором запросе:
{'cookies': {'initial': '1'}}

Работа с SSL-сертификатами и клиентской аутентификацией.

Пример python
session = requests.Session()
# Указание клиентского сертификата
session.cert = ('/path/to/client.cert', '/path/to/client.key')
# Отключение проверки сертификата (НЕ БЕЗОПАСНО для продакшена)
session.verify = False
# Или указание своего пучка сертификатов
# session.verify = '/path/to/ca_bundle.pem'

response = session.get('https://client-auth-required.example.com')

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

Пример python
with requests.Session() as s:
    s.headers.update({'Authorization': 'Bearer SECRET_TOKEN'})
    responses = []
    for page in range(1, 4):
        resp = s.get(f'https://api.example.com/data?page={page}')
        responses.append(resp.json())
    print(f'Получено страниц: {len(responses)}')
# Соединения корректно закрыты после выхода из блока with

питон requests.Session function comments

En
Requests.Session Create a persistent session for making requests