Requests.Session: примеры (PYTHON)
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-сертификатах по умолчанию. Рекомендуется всегда использовать актуальную версию библиотеки.
Расширенные и специальные примеры
Использование адаптеров для настройки количества повторных попыток и пула соединений.
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}')Использование хуков для глобальной обработки ответов или запросов.
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.
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')Имитация состояния браузера с сохранением и отправкой кук между запросами.
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-сертификатами и клиентской аутентификацией.
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')Использование сессии в контекстном менеджере для гарантированного освобождения ресурсов.
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