【学习笔记0005】Python中 requests.get 超时与重试

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

  • 12
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值