import requests
response = requests.get(url, timeout=(10, 15))
response.encoding ='utf-8'
html = response.text
timeout参数可以配置超时时间,一般情况我们只需要填一个数字,即可代表等待多少秒结束,但其实可以填一个元组的,要解释这个元组的作用,首先需要了解超时的两个概念:
A. 连接超时
连接超时是从客户端发起url请求,到与服务器建立起资源链接请求成功,中间所需要等待的最大时间
B. 读取超时
读取超时是客户端在与服务器已经建立资源链接请求成功后,开始获取资源并最后返回到客户端,中间所需要等待的最大时间
理解清楚以上两个概念后,我们回到参数 timeout 设置的元组 (10, 15),这里的连个数字分别代表 连接超时 和 读取超时,也就是说上诉代码在获取到url内容的结果之前,最多可能需要等待 10+15=25 秒,如果10秒之内(即连接超时时间内)还未成功获取资源则会触发
requests 包内置的重试机制,
关于这个机制,我后面再讲。
而通常情况下,我们设置超时时间只有一个数字,例如:
response = requests.get(url, timeout=10)
# response = requests.get(url, timeout=(10, 10)) # 效果等于上面代码
当只设置一个数字时,其实 requests 底层还是会当做两个数值即元组来处理,也就是说 requests 会将该数值
既作为连接超时又作为读取超时
去设置,那么最后在获取到url内容的结果之前,最多可能需要等待 10+10=20 秒,如果10秒之内(即连接超时时间内)还未成功则会触发重试机制。
最后讲一下我对 requests 重试机制的理解,众所周知攻城狮们不 FQ 的话,是肯定上不去 google 的,所以运行下面代码是肯定会报错且触发重试机制的:
import requests
from datetime import datetime
url = 'http://www.google.com'
print("开始......")
print(datetime.now())
response = requests.get(url)
response.encoding ='utf-8'
html = response.text
print(html)
输出情况如下:
结果分析:
可以看出上面出现了四次连接失败,requests 包在第一次去请求时,肯定是不知道是否能成功的,所以第一次不计入重试机制中的次数,那么重试机制的重试次数就是 4 – 1 = 3 次,当程序尝试3次后任然不成功,则返回。
思考:通常情况下,我们做爬虫经常会遇到被屏蔽的情况,而 requests 包自带的重试机制并不能满足实际需求,因为很少情况下是因为网络原因导致第一次请求不成功的,最有可能就是网站屏蔽了你的访问,那么重试机制里面的后面 3次请求就会显得没有意义,所以我们需要自己封装一个请求,让程序判断出请求异常时,就直接等待一段时间,然后再去重试请求。简单封装如下:
import requests, random, time
class Http():
def get_html(self, url):
try:
return self.__request(url)
except:
secends = random.randint(600, 1800)
print('出现异常,休息一会儿......')
print(str(secends) + '秒后继续')
time.sleep(secends) # 暂停10~30分钟,然后再尝试一次
try:
print('重试请求......')
return self.__request(url)
except:
print('出现异常,休息一会儿......')
print('30分钟后继续')
time.sleep(1800) # 暂停30分钟
return ''
def __request(self, url):
response = requests.get(url, timeout=(10, 15))
response.encoding ='utf-8'
return response.text
如有不对的地方,希望提出!共勉!2019-12-25 15:17:24