Таймауты в Python Requests: как задать, обработать и оптимизировать
Когда вы отправляете HTTP-запрос с помощью библиотеки requests, ваш код ждёт ответа от сервера. Если не указать значение таймаута, программа будет ждать бесконечно. Это состояние «ожидания навсегда» приводит к зависанию или тихим сбоям, когда сервер не отвечает вовсе. Чтобы этого избежать, в параметре timeout можно задать, сколько времени запрос должен ждать ответа. Без этого параметра код может выполняться бесконечно, не получив ни ответа, ни ошибки.
Опубликовано:
30.10.2025
Время чтения:
10 min
В этом руководстве разбирается, как правильно задавать таймаут, как реализовать повторные попытки для сессии или отдельного запроса и как не допустить, чтобы ваш Python-код застревал при не ответившем сервере.
Что такое таймауты в Python Requests

Таймаут определяет, сколько времени клиент ждёт ответа от сервера. В библиотеке requests это время состоит из двух этапов — соединения и получения данных. Таймаут соединения (connect timeout) определяет, сколько секунд программа будет пытаться установить подключение, а таймаут чтения (read timeout) — сколько времени она будет ждать данных после успешного соединения.
Эти значения можно указать одним числом, если одинаковое время подходит для обоих этапов, или кортежем из двух чисел, например timeout=(3, 10), чтобы управлять каждым из них отдельно.
Многие разработчики забывают задавать таймаут вовсе, из-за чего запросы начинают зависать и вести себя непредсказуемо. Понимание и корректное использование этого параметра — обязательное условие для любого, кто пишет надёжный код на Python.
Почему важно всегда использовать таймауты
Большинство неудачных запросов происходят из-за того, что таймауты просто не заданы. Когда соединение с API или Wi-Fi медленное, или вы парсите сайт с сотнями страниц, выполнение программы может зависнуть. Каждый запрос, который вы отправляете через библиотеку requests, должен иметь собственный таймаут — это сигнал для библиотеки, когда пора перестать ждать ответа.
Таймаут помогает программе быстрее реагировать на «тормозящие» или неработающие серверы. Вместо того чтобы бесконечно ждать, код получает ошибку, с которой можно работать: записать в лог, обработать, повторить запрос. Это особенно важно, если приложение делает десятки или сотни HTTP-запросов подряд, в том числе через прокси. Таймауты защищают от блокировок и уменьшают количество ошибок, возникающих из-за нестабильного соединения.
Как задавать таймауты в Python Requests
Параметр timeout можно указать как для каждого запроса отдельно, так и задать в общей логике работы программы. Наилучшей практикой считается всегда явно определять таймаут, не полагаясь на значения по умолчанию.
В библиотеке requests по умолчанию у параметра timeout значение None, что означает полное отсутствие ограничения по времени. Чтобы контролировать, как долго запрос будет ждать ответ, таймаут нужно указывать прямо при вызове функции — и он будет применён только к этому конкретному запросу.
Задание таймаута для одного запроса
Чтобы установить таймаут для отдельного запроса, достаточно передать его прямо в вызов функции.
Например:
requests.get("https://api.example.com", timeout=5)
В этом примере задан таймаут в 5 секунд. Значения указываются в секундах, но можно использовать и дробные числа, например 0.5. Короткие таймауты подходят для лёгких запросов вроде GET или HEAD, тогда как POST-запросы с телом данных обычно требуют большего времени ожидания. Если параметр timeout не указан, программа будет ждать бесконечно — до тех пор, пока сервер не ответит или соединение окончательно не зависнет. Этот пример наглядно показывает, как задать ограничение по времени для любого запроса, выполненного через библиотеку requests.
Раздельные таймауты для соединения и чтения
Таймауты можно разделять для двух этапов: подключения и получения данных. Для этого используется кортеж из двух чисел:
requests.get("https://api.example.com", timeout=(3, 10))
В этом случае программа будет ждать до трёх секунд, чтобы установить соединение, и до десяти секунд, чтобы получить ответ после подключения. Такой подход помогает быстрее пропускать «мертвые» или недоступные серверы, но при этом оставляет достаточно времени для медленных, перегруженных или удалённых ресурсов, где получение данных занимает дольше обычного.
Обработка исключений при таймаутах
При работе с сетью в Python важно подбирать значения таймаута под реальные условия соединения. Малое значение делает запросы более отзывчивыми, но слишком короткое приведёт к ложным ошибкам. Чтобы корректно обрабатывать ситуации, когда сервер не отвечает, необходимо использовать блок try/except. Это позволит отлавливать ошибки, записывать их в логи и завершать выполнение безопасно, не обрушивая всю программу.
Таймаут — это не сбой в коде, а признак того, что сервер не успел ответить вовремя. Поэтому логика обработки здесь иная: нужно не исправлять код, а корректно реагировать на отсутствие отклика.
Основные типы исключений при таймаутах
Библиотека requests использует несколько типов исключений, связанных с таймаутами.
requests.exceptions.Timeout — общее исключение, охватывающее все случаи превышения времени ожидания.
ConnectTimeout возникает, когда соединение не удаётся установить достаточно быстро.
ReadTimeout срабатывает, если данные перестали поступать после подключения.
Кроме того, возможно общее исключение RequestException, которое охватывает другие ошибки при выполнении запросов.
Хорошая практика — выводить понятные сообщения об ошибках и фиксировать изменения таймаутов в логах. В некоторых случаях, например при временных сбоях сети, можно повторить запрос. Но если таймауты повторяются, это чаще всего указывает на более серьёзные проблемы с сетью или сервером.
Использование сессий для задания таймаутов по умолчанию
Сессии в Python позволяют один раз задать параметр таймаута и применять его ко всем исходящим запросам. Это делает работу приложения предсказуемой и избавляет от необходимости указывать таймаут вручную при каждом вызове.
Объект Session из библиотеки requests повторно использует открытые соединения, что снижает нагрузку и ускоряет выполнение запросов. При этом можно создать вспомогательную функцию или обёртку над методом Session.request, чтобы использовать разные значения таймаутов в зависимости от контекста — например, короткий для быстрых API-запросов и более длинный для операций, требующих передачи больших данных. Такой подход помогает держать всю логику таймаутов в одном месте и упрощает сопровождение кода.
Таймауты в асинхронных и многопоточных средах
В асинхронных Python-скриптах таймауты можно и нужно задавать для каждой задачи отдельно. Это гарантирует, что каждый запрос завершится корректно — либо ответом, либо контролируемым исключением, но не зависанием.
В многопоточной среде, например при использовании ThreadPoolExecutor, каждый поток будет работать со стандартными таймаутами библиотеки requests.
Для асинхронных приложений на asyncio или aiohttp таймауты задаются иначе. Можно установить общий предел ожидания для задачи с помощью future.result(timeout=10) или использовать параметр ClientTimeout, например:
import aiohttp
timeout = aiohttp.ClientTimeout(total=30, connect=5, sock_read=20)
Параметр total ограничивает общее время выполнения запроса, connect задаёт время подключения, а sock_read — время ожидания получения данных. Для большинства API-запросов подходят небольшие значения, а для сетевых операций, где данные могут приходить дольше, стоит использовать более продолжительные таймауты.
Частые проблемы с таймаутами и как их решать
Большинство проблем с таймаутами в Python возникает просто потому, что значения заданы неправильно или не заданы вообще. Таймауты нужно подстраивать под реальную скорость сервера и качество сети. Ниже — типичные ситуации и что с ними делать.
Отсутствует обработка таймаута
Если не указать таймаут при подключении, код может зависнуть навсегда. Хуже того, если во время установки соединения или при его закрытии произойдёт исключение, а вы его не перехватываете, это может положить всё приложение, а не только один запрос. Исправляется это минимальными усилиями: задайте таймаут по умолчанию, используйте общую сессию с повторными попытками и обязательно ловите исключения, чтобы не падать целиком.
Проблемы сети и задержки на прокси
Нестабильная сеть, мобильный интернет или работа через прокси почти всегда означают повышенную задержку. Это нормально, но, если таймаут слишком короткий, вы будете получать ложные ошибки. В таких условиях имеет смысл увеличить таймауты, чтобы не рвать рабочие соединения слишком агрессивно. Таймауты можно подбирать отдельно для разных API или для «тяжёлых» HTTP-запросов с большим объёмом данных. Так вы снижаете риск блокировок и постоянных обрывов соединения в нестабильной среде.
Медленный DNS или медленный бэкенд
Если DNS-разрешение занимает заметное время, сам этап подключения становится дольше. В этом случае логично поднять connect timeout. Если проблема не в подключении, а в том, что сервер отвечает очень медленно и отдаёт данные по кускам, то нужно увеличивать read timeout или общее ограничение по времени запроса. Иначе вы будете получать исключения не потому, что сервер умер, а просто потому, что он медленный.
Рекомендации по использованию таймаутов
Лучше всегда задавать таймауты явно, а не полагаться на значения по умолчанию. Для подключения и получения данных стоит использовать разные значения — одно для соединения, другое для чтения. Это помогает точнее контролировать поведение запросов.
Полезно вести логи не только ошибок, но и времени, затраченного на каждый запрос — это упрощает отладку и поиск проблем. Если используется механизм повторных попыток, добавляйте «джиттер» или постепенную задержку между ними, чтобы избежать бесконечных циклов повторов и лишней нагрузки на сервер.
Для любого HTTP-запроса, выполненного через requests, следует указывать таймаут. Грамотно настроенные значения сокращают количество повторов, предотвращают зависания и делают работу приложения стабильнее.
Практические примеры
Пример 1. Веб-скрапинг
При массовых HTTP-запросах для парсинга сайтов удобно хранить настройки таймаутов отдельно для каждого домена. Для быстрых сайтов лучше задавать короткие лимиты, для тяжёлых страниц — более длинные. Оптимально использовать сессию с адаптером, поддерживающим повторные попытки при ответах 429 (Too Many Requests) или 5xx (ошибки сервера). В логах стоит фиксировать время отклика, чтобы отслеживать проблемы с производительностью или нестабильными хостами.
Пример 2. Автоматизация работы с API (на примере GitHub)
При работе с API, например GitHub, разумно использовать разные таймауты для разных типов запросов. GET-запросы обычно выполняются быстрее и могут иметь короткий таймаут, тогда как POST-запросы с передачей большого объёма данных требуют большего лимита ожидания. Исключения по таймауту следует перехватывать и повторять запрос один-два раза, чтобы избежать потери данных. Все результаты и ошибки нужно логировать — это поможет видеть динамику ответов и вовремя замечать сбои.
Пример 3. Локальное приложение
В локальных сценариях или при работе микросервисов стоит использовать более короткие таймауты — задержка внутри одной сети обычно минимальна, поэтому большие значения не нужны. Также важно ограничить количество повторных попыток, чтобы избежать бесконечных ретраев при сбоях внутри локальной инфраструктуры.
Полезно добавить уведомления о таймаутах и слишком долгих ответах: если сервис на одной сети внезапно «молчит», это почти всегда сигнал о проблеме с конкретным узлом, зависшем процессе или конфликте соединений.
Альтернативы библиотеке Python Requests
Существуют и другие библиотеки, которые предоставляют более гибкое управление таймаутами.
HTTPX поддерживает как синхронные, так и асинхронные запросы, предлагая единую удобную модель настройки таймаутов.
Aiohttp даёт детальный контроль над поведением асинхронных запросов и подойдёт для сложных сетевых сценариев.
Urllib3 обеспечивает низкоуровневое управление соединениями и параметрами HTTP-запросов, что полезно при нестандартных требованиях.
Все эти инструменты пригодятся, если нужно больше гибкости, чем предлагает стандартная библиотека requests, особенно при работе с неблокирующими или высоконагруженными задачами.
Заключение
Работу с сетью всегда нужно начинать с правильно заданных таймаутов — отдельно для подключения и для чтения данных. Логи времени выполнения помогают отслеживать производительность, а повторные попытки стоит использовать с осторожностью, чтобы не перегружать сервер и не нарушать стабильность приложения.
Если ваше приложение работает с большим количеством сетевых запросов, особенно при высоких скоростях, оптимизация таймаутов и корректная обработка ошибок значительно улучшат его надёжность. Таймаут в Python — это не дополнительная опция, а обязательная часть любого запроса. Всегда указывайте его явно, чтобы ваш код оставался предсказуемым и управляемым.
В этой статье
- Что такое таймауты в Python Requests
- Почему важно всегда использовать таймауты
- Как задавать таймауты в Python Requests
- Обработка исключений при таймаутах
- Использование сессий для задания таймаутов по умолчанию
- Таймауты в асинхронных и многопоточных средах
- Частые проблемы с таймаутами и как их решать
- Рекомендации по использованию таймаутов
- Практические примеры
- Альтернативы библиотеке Python Requests
- Заключение
Готовы начать?
Похожие статьи


