除了 ConnectionError 或 TimeoutError 不起作用

Posted

技术标签:

【中文标题】除了 ConnectionError 或 TimeoutError 不起作用【英文标题】:except ConnectionError or TimeoutError not working 【发布时间】:2017-09-08 12:57:12 【问题描述】:

如果出现连接错误,我希望 Python 等待并重试。这是相关代码,其中“链接”是一些链接:

import requests
import urllib.request
import urllib.parse

from random import randint

try:
    r=requests.get(link)

except ConnectionError or TimeoutError:
    print("Will retry again in a little bit")
    time.sleep(randint(2500,3000))
    r=requests.get(link)

除了我仍然定期收到连接错误。而且我从来没有看到“稍后将重试”的文字,所以我知道代码没有重试。我究竟做错了什么?我在下面粘贴部分错误代码,以防我误读了错误。蒂亚!

TimeoutError: [WinError 10060] 连接尝试失败,因为连接方在一段时间后没有正确响应,或者连接失败,因为连接的主机没有响应

在处理上述异常的过程中,又发生了一个异常:

requests.packages.urllib3.exceptions.ProtocolError: ('Connection aborted.', TimeoutError(10060, '连接尝试失败,因为连接方在一段时间后没有正确响应,或者建立连接失败,因为连接的主机没有响应', None, 10060, None))

在处理上述异常的过程中,又发生了一个异常:

requests.exceptions.ConnectionError: ('Connection aborted.', TimeoutError(10060, '连接尝试失败,因为连接方在一段时间后没有正确响应,或者建立连接失败,因为连接的主机没有响应',无,10060,无))

【问题讨论】:

【参考方案1】:

对我来说,在请求中使用自定义用户代理可以解决此问题。使用这种方法,您可以欺骗您的浏览器。

作品:

url = "https://www.nasdaq.com/market-activity/stocks/amd"
headers = 'User-Agent': 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.6) Gecko/20070802 SeaMonkey/1.1.4'
response = requests.get(url, headers=headers)

不起作用:

url = "https://www.nasdaq.com/market-activity/stocks/amd"
response = requests.get(url)

【讨论】:

【参考方案2】:

第二个请求不在 try 块内,因此不会捕获异常。此外,在 try-except 块中,您不会捕获其他可能发生的异常。 您可以使用循环尝试连接两次,如果请求成功则中断。

for _ in range(2):
    try:
        r = requests.get(link)
        break
    except (ConnectionError, TimeoutError):
        print("Will retry again in a little bit")
    except Exception as e:
        print(e)
    time.sleep(randint(2500,3000))

【讨论】:

谢谢,试试这个!问题:这个循环会一直休眠 2500-3000 秒还是仅在发生连接错误时才休眠?我想要后者,但看起来这段代码正在做前者。 仅在出错时。如果请求成功,break 语句会在调用 time.sleep 之前中断循环。【参考方案3】:

我认为你应该使用

except (ConnectionError, TimeoutError) as e:
    print("Will retry again in a little bit")
    time.sleep(randint(2500,3000))
    r=requests.get(link)

查看this类似问题,或查看docs。

【讨论】:

谢谢!在这种情况下“通过”会做什么?导致“尝试”下的代码再次重新运行?另外,我确实想让脚本在重试之前等待一段不平凡的时间,而您的建议似乎没有这样做。 pass 什么都不做,你应该用你的代码替换它。您应该将您拥有的任何代码保留在 except 块中,即您的 time.sleep 调用等。我已经编辑了我的答案以在 except 块中使用您的代码。很抱歉造成混乱。 有道理,谢谢!我更新了我的代码并重新运行它只是为了确保这解决了问题。 在这种情况下真的有理由分配别名e 吗?你再也不会使用它了。 except (ConnectionError, TimeoutError): 就足够了。 我试过这个版本,并没有解决问题。在没有打印“稍后将重试”并重试的情况下仍然出现 Connection/TimeoutError 故障。【参考方案4】:

我遇到了同样的问题。原来 urlib3 依赖于 socket.py,这会引发 OSError。所以,你需要抓住这一点:

try:
    r = requests.get(link)
except OSError as e:
    print("There as an error: ".format(e))

【讨论】:

以上是关于除了 ConnectionError 或 TimeoutError 不起作用的主要内容,如果未能解决你的问题,请参考以下文章

ConnectionError:无法连接到 database server - 无法连接(序列)

尝试/除了使用 Python requests 模块的正确方法?

Apple 通知失败:ID=2,代码=ConnectionError

如何处理“Redis.exceptions.ConnectionError:连接有数据”

“requests.exceptions.ConnectionError: ('Connection aborted.', RemoteDisconnected('Remote end closed

python requests.exceptions.ConnectionError