Почему request.get() не возвращается? Каков тайм-аут по умолчанию, который использует функция request.get()?

В моем script, requests.get никогда не возвращается:

import requests

print ("requesting..")

# This call never returns!
r = requests.get(
    "http://www.justdial.com",
    proxies = {'http': '222.255.169.74:8080'},
)

print(r.ok)

Какая может быть возможная причина? Любое средство? Каков тайм-аут по умолчанию, который использует get?

Ответ 1

Каков тайм-аут по умолчанию, который использует использование?

Тайм-аут по умолчанию - None, что означает, что он будет ждать (зависает), пока соединение не будет закрыто.

Что происходит, когда вы передаете значение тайм-аута?

r = requests.get(
    'http://www.justdial.com',
    proxies={'http': '222.255.169.74:8080'},
    timeout=5
)

Ответ 2

От запрашивает документацию:

Вы можете сказать "Запросы" прекратить ожидание ответа после заданного количество секунд с параметром таймаута:

>>> requests.get('http://github.com', timeout=0.001)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
requests.exceptions.Timeout: HTTPConnectionPool(host='github.com', port=80): Request timed out. (timeout=0.001)

Примечание:

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

Мне очень часто случается, что request.get() занимает очень много времени, даже если timeout - 1 секунда. Есть несколько способов преодолеть эту проблему:

1. Используйте внутренний класс TimeoutSauce

От: https://github.com/kennethreitz/requests/issues/1928#issuecomment-35811896

import requests from requests.adapters import TimeoutSauce

class MyTimeout(TimeoutSauce):
    def __init__(self, *args, **kwargs):
        connect = kwargs.get('connect', 5)
        read = kwargs.get('read', connect)
        super(MyTimeout, self).__init__(connect=connect, read=read)

requests.adapters.TimeoutSauce = MyTimeout

Этот код должен заставлять нас устанавливать таймаут чтения равным время ожидания подключения, которое является значением тайм-аута, которое вы передаете на своем Session.get(). (Обратите внимание, что я на самом деле не протестировал этот код, поэтому может потребоваться некоторая быстрая отладка, я просто написал это прямо в Окно GitHub.)

2. Используйте вилку запросов от kevinburke: https://github.com/kevinburke/requests/tree/connect-timeout

Из документации: https://github.com/kevinburke/requests/blob/connect-timeout/docs/user/advanced.rst

Если вы укажете одно значение для таймаута, например:

r = requests.get('https://github.com', timeout=5)

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

r = requests.get('https://github.com', timeout=(3.05, 27))

ПРИМЕЧАНИЕ: С тех пор это изменение было объединено с основным проектом "Запросы" .

3. Используя evenlet или signal, как уже упоминалось в аналогичном вопросе: Тайм-аут для всего запроса python request.get

Ответ 3

Просмотрел все ответы и пришел к выводу, что проблема все еще существует. На некоторых сайтах запросы могут бесконечно зависать, и использование многопроцессорности, похоже, слишком велико. Здесь мой подход (Python 3.5 +):

import asyncio

import aiohttp


async def get_http(url):
    async with aiohttp.ClientSession(conn_timeout=1, read_timeout=3) as client:
        try:
            async with client.get(url) as response:
                content = await response.text()
                return content, response.status
        except Exception:
            pass


loop = asyncio.get_event_loop()
task = loop.create_task(get_http('http://example.com'))
loop.run_until_complete(task)
result = task.result()
if result is not None:
    content, status = task.result()
    if status == 200:
        print(content)