Почему тайм-аут модуля «запросы» не работает в python3? - PullRequest
4 голосов
/ 07 апреля 2020

Я хочу получить содержимое URL-адреса, а в тех случаях, когда я сталкиваюсь с 50X Кодами ошибок HTTP, повторите попытку 10 раз с задержкой 0,5 секунды между повторными попытками. Я также хочу иметь 1-секундный тайм-аут для моих запросов. Для достижения этой цели я попробовал следующую программу:

#!/usr/bin/python3

import sys
import requests
from urllib3.util.retry import Retry
from requests.adapters import HTTPAdapter    

URL = "http://<DOMAIN>/Loader.aspx?ParTree=15131H&i=" # + stockid


def get_data(stockid):

    print("1")
    req_session = requests.Session()

    print("2")
    retries = Retry(total = 10, 
                    backoff_factor = 0.5,
                    status_forcelist = [500, 502, 503, 504])

    print("3")
    req_session.mount("http://", HTTPAdapter(max_retries=retries))

    print("4")
    page_content = req_session.get(URL + stockid, timeout=1).content

    print("5")

get_data(sys.argv[1])

К сожалению, она зависает на несколько минут после печати 4 на экране. Что не так?

1 Ответ

1 голос
/ 08 апреля 2020

Я, прежде всего, Windows пользователь. Ваш timeout работает нормально. Здесь backoff_factor создает проблему. Попробуйте:

#!/usr/bin/python3

import sys
import requests
from requests.packages.urllib3.util.retry import Retry # requests.packages. is not necessary
from requests.adapters import HTTPAdapter    

URL = "http://<DOMAIN>/Loader.aspx?ParTree=15131H&i=" # + stockid


def get_data(stockid):

    print("1")
    req_session = requests.Session()

    print("2")
    retries = Retry(total = 10, 
                    backoff_factor = 0.5,
                    status_forcelist = [500, 502, 503, 504])
    requests.packages.urllib3.util.Retry.BACKOFF_MAX = 0.5 # required
    # requests.packages. is not necessary
    # it isin't necessary you have to mount this way
    print("3")
    adapter = HTTPAdapter(max_retries=retries)
    req_session.mount('http://', adapter)
    req_session.mount('https://', adapter)

    print("4")
    page_content = req_session.get(URL + stockid, timeout=1).content

    print("5")

get_data(sys.argv[1])

Этот способ также возможен:

retries = RetryRequest(
        total=10,
        backoff_factor=0.5,
        status_forcelist=[500, 502, 503, 504],
        max_backoff=backoff_factor)

Документировано, что при использовании backoff_factor:

Это будет никогда не будет длиннее Retry.BACKOFF_MAX (что по умолчанию 120).

Поэтому, когда вы пробуете свою ссылку, BACKOFF_MAX предшествует вашему backoff_factor, что увеличивает время выполнения. Следовательно, установка:

requests.packages.urllib3.util.Retry.BACKOFF_MAX = 0.5

поможет вам.
Но эту ошибку не следует поднимать, поскольку она определяется как:

min(self.BACKOFF_MAX, backoff_value)

in:

urllib3.util.retry
...