Таймаут (timeout)



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

Timeout позволяет указать время, которое метод .get() будет ожидать ответа от сервера. Указывается в виде секунд.

Значение может быть числом, например, timeout=3, будет ожидание 3 секунды. Также можно использовать кортежи для разделения времени на два отдельных периода – подключение (connect timeout) и чтение (read timeout). Например, конструкция timeout=(3, 27) позволяет установить тайм-аут подключения в 3 секунды и тайм-аут чтения в 27 секунд.

Если установить значение в None, время ожидание ответа не будет ограничиваться. Это может привести к зависанию программы, при этом не будет возможности установить источник проблемы.

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

Обработка исключений

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

import requests
try:
    response = requests.get("http://example.com", timeout=.1)
except Exception as e:
    # Узнаем имя возникшего исключения
    print(e.__class__.__name__)

Данный код выведет ConnectTimeout. Это тип исключения, который часто встречается при работе с сетевыми запросами, означает, что сервер не ответил в отведенное время. Это не всегда означает, что сервер полностью неработоспособен, возможно, возникли временные проблемы. Также могут быть просто проблемы с сетью.

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

import requests

from requests.exceptions import ConnectTimeout
try:
    response = requests.get("http://example.com", timeout=5)  # timeout в секундах
except ConnectTimeout:
    print("Connection to the server timed out.")
    # Здесь могут быть дополнительные действия, например, повторный запрос или логирование ошибки.

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

import requests
import time
url = 'http://httpbin.org/get'
proxies = {
    'http': 'http://200.12.55.90:80',
    'https': 'http://200.12.55.90:80'
}
start = time.perf_counter()
try:
    requests.get(url=url, proxies=proxies)
except requests.exceptions.ProxyError as e:
    print(f'wait time = {time.perf_counter() - start}')
    print(e)

Время ожидание составило более 20 секунд. Чтобы сократить время ожидания, достаточно добавить атрибут timeout=1.

import requests
import time

url = 'http://httpbin.org/get'
proxies = {
    'http': 'http://200.12.55.90:80',
    'https': 'http://200.12.55.90:80'
}
start = time.perf_counter()
try:
    requests.get(url=url, proxies=proxies, timeout=1)
except requests.exceptions.ProxyError as e:
    print(f'wait time = {time.perf_counter() - start}')
    print(e)

ConnectTimeoutError – класс исключения, указывающий, что время установленное время ожидание превышено.

У начинающих пользователей может возникнуть вопрос, почему при работе с proxy обрабатывается requests.exceptions.ProxyError.

В библиотеке requests при работе с прокси все исключения, непосредственно связанные с работой через прокси-сервер, оборачиваются в ProxyError. Это позволяет более четко понимать контекст ошибки. Таймаут подключения – это частный случай ошибки соединения, и если он происходит в контексте работы с прокси, то requests считает это частью ошибки прокси.

Принцип работы:

Когда делается запрос через прокси, библиотека использует urllib3для управления низкоуровневыми операциями с сетью.

Если возникает таймаут в процессе установки соединения через прокси, urllib3 генерирует исключение ConnectTimeoutError.

Далее библиотека requests перехватывает данное исключение и оборачивает его в ProxyError, при этом добавляется информация, что ошибка связана с работой прокси-сервера.

Если попытаться перехватить штатное исключение Timeout, обработчик не сработает для таймаутов, которые возникают в контексте прокси. Это обусловлено тем, что теперь они представлены в формате ProxyError.



Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: