【问题标题】:Why "requests" module timeout doesn't work in python3?为什么“请求”模块超时在 python3 中不起作用?
【发布时间】:2020-04-07 20:04:32
【问题描述】:

我想获取 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 后冻结了几分钟。怎么了?

【问题讨论】:

  • 如何调用您的代码?这意味着:sys.argv[1] 是什么?
  • id 没有使用,所以不需要...
  • @Manuel 抱歉打错了。我编辑了这个问题。谢谢。
  • 它适用于可访问的 url。请给我们完整的链接
  • @InfinityTM 由于 Web 服务器的行为不是确定性的,因此添加此类信息并没有多大帮助。可访问的 URL 没有问题,如果网络服务器未在预期时间内响应,则会出现此问题。

标签: python-3.x python-requests urllib3


【解决方案1】:

首先,我是 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)

在:

urllib3.util.retry

【讨论】:

  • backoff_factor是失败请求之间的延迟时间吗?
  • backoff_factor 就像sleep(),它在重试之间休眠一段特定的时间
  • 好的。我不明白为什么我必须更改BACKOFF_MAX。正如我从您对 API 文档的引用中了解到的,我的 backoff_factor 必须小于 BACKOFF_MAX。但是为什么我需要改变BACKOFF_MAX的值呢?
  • 我会在这方面投入一点时间后再回复
  • IPTable 规则使主机丢弃数据包。它不返回任何响应。正如您之前所说,所有问题都与 backoff_factor 角色有关。它没有线性效应。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-19
  • 2021-05-20
相关资源
最近更新 更多