Я собираю статистику по списку сайтов и использую запросы для простоты. Вот мой код:
data=[]
websites=['http://google.com', 'http://bbc.co.uk']
for w in websites:
r= requests.get(w, verify=False)
data.append( (r.url, len(r.content), r.elapsed.total_seconds(), str([(l.status_code, l.url) for l in r.history]), str(r.headers.items()), str(r.cookies.items())) )
Теперь я хочу requests.get
сделать тайм-аут через 10 секунд, чтобы цикл не застрял.
Этот вопрос был интересен , прежде чем тоже , но ни один из ответов не являются чистыми. Я возложу на это награду, чтобы получить хороший ответ.
Я слышал, что, возможно, не использовать запросы - это хорошая идея, но тогда как мне получить хорошие предложения запросов? (те, в кортеже)
python
timeout
python-requests
Kiarash
источник
источник
Ответы:
Как насчет использования eventlet? Если вы хотите тайм-аут запроса через 10 секунд, даже если данные получены, этот фрагмент кода будет работать для вас:
источник
eventlet.monkey_patch()
требуется?socket
модуль должен быть исправлен обезьяной, так что, по крайней мере, вам понадобитсяeventlet.monkey_patch(socket=True)
requests.get('https://github.com', timeout=5)
Установите параметр времени ожидания :
Пока вы не настроите
stream=True
этот запрос, это приведетrequests.get()
к истечению времени ожидания вызова, если соединение займет более десяти секунд или если сервер не отправляет данные более десяти секунд.источник
ОБНОВЛЕНИЕ: https://requests.readthedocs.io/en/master/user/advanced/#timeouts
В новой версии
requests
:Если вы указываете одно значение для тайм-аута, например так:
Значение тайм-аута будет применено как
connect
кread
тайм-аутам, так и к тайм-аутам. Укажите кортеж, если вы хотите установить значения отдельно:Если удаленный сервер работает очень медленно, вы можете попросить Requests вечно ждать ответа, передав None в качестве значения тайм-аута, а затем получив чашку кофе.
Мой старый (вероятно, устаревший) ответ (который был опубликован давно):
Есть и другие способы преодоления этой проблемы:
1. Используйте
TimeoutSauce
внутренний классОт: https://github.com/kennethreitz/requests/issues/1928#issuecomment-35811896
2. Используйте форк запросов от kevinburke: https://github.com/kevinburke/requests/tree/connect-timeout
Из его документации: https://github.com/kevinburke/requests/blob/connect-timeout/docs/user/advanced.rst
kevinburke попросил включить его в проект основных запросов, но он еще не принят.
источник
this won't work for you use-case
. Он имел в виду, что он не работает с mp3 потоком, который хочет другой парень.timeout = int(seconds)
Так как
requests >= 2.4.0
вы можете использоватьtimeout
аргумент, а именно:Примечание:
источник
Для создания тайм-аута вы можете использовать сигналы .
Лучший способ решить это дело, вероятно,
try-except-finally
блока.Вот пример кода:
Есть некоторые оговорки к этому:
Но это все в стандартной библиотеке Python! За исключением импорта функции сна, это только один импорт. Если вы собираетесь использовать тайм-ауты во многих местах, вы можете легко поместить TimeoutException, _timeout и singaling в функцию и просто вызвать это. Или вы можете сделать декоратор и поставить его на функции, см. Ответ ниже.
Вы также можете настроить это как «менеджер контекста», чтобы использовать его с
with
оператором:Один из возможных недостатков этого подхода к контекстному менеджеру заключается в том, что вы не можете знать, истек ли срок действия кода или нет.
Источники и рекомендуемое чтение:
источник
Попробуйте этот запрос с тайм-аутом и обработкой ошибок:
источник
Установить
stream=True
и использоватьr.iter_content(1024)
. Да,eventlet.Timeout
просто как-то у меня не работает.Обсуждение здесь https://redd.it/80kp1h
источник
Это может быть излишним, но очередь распределенных задач Celery имеет хорошую поддержку для тайм-аутов.
В частности, вы можете определить мягкое ограничение по времени, которое просто вызывает исключение в вашем процессе (чтобы вы могли очистить), и / или жесткое ограничение по времени, которое завершает задачу при превышении этого срока.
Под прикрытием здесь используется тот же подход к сигналам, на который ссылается ваша публикация «до», но в более удобной и управляемой форме. И если список веб-сайтов, которые вы отслеживаете, очень длинный, вы можете воспользоваться его основной функцией - всеми видами способов управления выполнением большого количества задач.
источник
python-requests
сhttplib
(используется запросами для Python 2.7). Пакет передает все, что связаноtimeout
непосредственно с httplib. Я думаю, что ничто не может быть исправлено в запросе, потому что процесс может долго оставаться в httplib.Я считаю, что вы можете использовать
multiprocessing
и не зависеть от стороннего пакета:Тайм-аут, на который передается
kwargs
тайм-аут для получения любого ответа от сервера, аргументtimeout
- это тайм-аут для получения полного ответа.источник
timeout = (тайм-аут соединения, тайм-аут чтения данных) или указать один аргумент (timeout = 1)
источник
этот код работает для socketError 11004 и 10060 ......
источник
Несмотря на вопрос о запросах, я считаю, что это очень легко сделать с помощью pycurl CURLOPT_TIMEOUT или CURLOPT_TIMEOUT_MS.
Нет потоков или сигнализации требуется:
источник
Если вы используете опцию,
stream=True
вы можете сделать это:Решение не требует сигналов или многопроцессорной обработки.
источник
Просто еще одно решение (получено от http://docs.python-requests.org/en/master/user/advanced/#streaming-uploads )
Перед загрузкой вы можете узнать размер контента:
Но будьте осторожны, отправитель может установить неправильное значение в поле ответа «длина содержимого».
источник
Если дело доходит до этого, создайте сторожевой поток, который через 10 секунд портит внутреннее состояние запросов, например:
Обратите внимание, что в зависимости от системных библиотек вы можете не установить крайний срок разрешения DNS.
источник
Ну, я попробовал много решений на этой странице и все еще сталкивался с нестабильностью, случайными зависаниями, низкой производительностью соединений.
Сейчас я использую Curl, и я очень доволен его функциональностью «максимального времени» и глобальными показателями, даже с такой плохой реализацией:
Здесь я определил параметр максимального времени 6 секунд, включающий как соединение, так и время передачи.
Я уверен, что у Curl есть хорошая привязка к Python, если вы предпочитаете придерживаться синтаксиса Python :)
источник
Существует пакет под названием timeout-decorator, который вы можете использовать для тайм-аута любой функции python.
Он использует подход сигналов, что некоторые ответы здесь предлагают. В качестве альтернативы вы можете сказать ему использовать многопроцессорную обработку вместо сигналов (например, если вы находитесь в многопоточном окружении).
источник
Я использую запросы 2.2.1 и eventlet не работает для меня. Вместо этого я смог использовать время ожидания Gevent, поскольку Gevent используется в моем сервисе для gunicorn.
Обратите внимание, что gevent.timeout.Timeout не перехватывается общей обработкой исключений. Так что либо явно перехватите,
gevent.timeout.Timeout
либо передайте другое исключение для использования следующим образом:with gevent.Timeout(5, requests.exceptions.Timeout):
хотя при возникновении этого исключения сообщение не передается.источник
Я придумал более прямое решение, которое, по общему признанию, некрасиво, но исправляет реальную проблему. Это выглядит примерно так:
Вы можете прочитать полное объяснение здесь
источник
timeout
параметрrequests.get()
без отвратительных обходных путей 2 - хотя оба не будут ограничивать общее время ожидания в отличие отeventlet.Timeout(10)