领取资料,咨询答疑,请➕wei: June__Go
上一节,我们学习了requests的重定向和请求历史,本小节我们讲解一下,requests的超时与重试。
什么是超时?
1、连接超时
连接超时指的是没连接上,超过指定的时间内都没有连接上,这就是连接超时。(连接时间就是httpclient发送请求的地方开始到连接上目标主机url地址的时间)
连接超时示例:
import time
import requests
url = 'http://www.google.com.hk'
print(time.strftime('%Y-%m-%d %H:%M:%S'))
try:
html = requests.get(url, timeout=5).text
print('success')
except requests.exceptions.RequestException as e:
print(e)
print(time.strftime('%Y-%m-%d %H:%M:%S'))
运行结果:
2024-01-03 22:06:54
HTTPConnectionPool(host='www.google.com.hk', port=80): Max retries exceeded with url: / (Caused by ConnectTimeoutError(<urllib3.connection.HTTPConnection object at 0x0000020032FDA0A0>, 'Connection to www.google.com.hk timed out. (connect timeout=5)'))
2024-01-03 22:06:59
2、读取超时
读取超时表示的是连接上了,但是读数据时超过了指定的时间范围,这就是读取超时(读取时间就是HttpClient已经连接到了目标服务器,然后进行内容数据的获取的时间)
读取超时示例:
import time
import requests
try:
r = requests.get('https://github.com', timeout=(1, 2))
print('success')
except requests.exceptions.RequestException as e:
print(e)
print(time.strftime('%Y-%m-%d %H:%M:%S'))
运行结果:
HTTPSConnectionPool(host='github.com', port=443): Read timed out. (read timeout=2)
2024-01-03 21:32:58
requests如何设置超时时间?
requests的超时时间是通过timeout字段来设置的,有以下两种情况
1、如果你设置了一个单一的值作为 timeout,如下所示:
r = requests.get('https://github.com', timeout=5)
这一 timeout 值将会用作连接超时和读取超时二者的timeout,即都为5s
2、如果要分别制定连接超时和读取超时,就传入一个元组:
r = requests.get('https://github.com', timeout=(3.05, 27))
为什么要设置超时重试?
比如连接超时,程序就一直处于无响应状态。这时我们需要去不断重试连接,但也不可能是无止境的去重试,所以需要设置一个timeout超时时间。在timeout超时时间内如果无法连接到目标主机url地址,就返回一个异常错误(将这个连接超时的的特殊url写到log日志中,方便管理员查看;读取的数据量大,或者是目标服务器本身的问题(比如读取数据库慢,并发量大等...)也会影响读取时间也可以设置读取超时就返回报错。方便业务管理和问题定位)
超时重试
一般超时我们不会立即返回,而会设置一个三次重连的机制。
def gethtml(url):
i = 0
while i < 3:
try:
html = requests.get(url, timeout=5).text
return html
except requests.exceptions.RequestException:
i += 1
其实 requests 已经帮我们封装好了。(但是代码好像变多了…)
import time
import requests
from requests.adapters import HTTPAdapter
s = requests.Session()
s.mount('http://', HTTPAdapter(max_retries=3))
s.mount('https://', HTTPAdapter(max_retries=3))
print(time.strftime('%Y-%m-%d %H:%M:%S'))
try:
r = s.get('http://www.google.com.hk', timeout=5)
except requests.exceptions.RequestException as e:
print(e)
print(time.strftime('%Y-%m-%d %H:%M:%S'))
max_retries 为最大重试次数,重试3次,加上最初的一次请求,一共是4次,所以上述代码运行耗时是20秒而不是15秒
运行结果:
2024-01-03 21:46:57
HTTPConnectionPool(host='www.google.com.hk', port=80): Max retries exceeded with url: / (Caused by ConnectTimeoutError(<urllib3.connection.HTTPConnection object at 0x000001D4FBAB78B0>, 'Connection to www.google.com.hk timed out. (connect timeout=5)'))
2024-01-03 21:47:17
最后感谢每一个认真阅读我文章的人,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走,希望可以帮助到大家!领取资料,咨询答疑,请➕wei: June__Go