前言

在爬虫过程中,经常会由于一些网络或其他不可控因素,从而遇到一些功能性问题。比如在发送请求时,会因为网络不稳定,往往会有请求超时的问题。这种情况下,我们通常会在代码中加入重试的代码。重试的代码本身不难实现,但如何写得优雅、易用,是我们要考虑的问题。

Tenacity是一个通用的retry库,简化为任何任务加入重试的功能,它实现了几乎我们可以使用到的所有重试场景。先pip为敬:

pip install tenacity

不懂这个库怎么用, 很简单,哦对了,可能还需要你知道装饰器就是那个@啦就够了,上菜!

无条件重试,重试之间无间隔

import tenacityimport requests# 直接加上retry装饰器,代码抛出异常会一直重试,直到代码运行成功
@tenacity.retry()
def baidu():response = requests.get(url = 'http://www.baidu.com')if response.status_code == 200:return response.textraise Exceptionres = baidu()
print(res)

这里呢,我们使用requests请求了百度,并输出response,在code=200的位置上,如果code不等于200,这个程序就会被retry重试。理就是这么个理,够不够优雅?

无条件重试,但是在重试之前要等待 3秒:

from tenacity import retry , stop_after_attempt , stop_after_delay , wait_fixedimport requests# 在程序重试前固定等待时间
@retry(wait = wait_fixed(3))
def baidu():web = requests.get(url = 'http://www.baidu.com')if web.status_code == 200:return web.textraise Exception
res = baidu()
print(res)

设置停止的基本条件

只重试3次

from tenacity import retry,stop_after_attemptimport requests# 加上终止条件的retry
# 重试三次之后不再重试
@retry(stop=stop_after_attempt(3))
def baidu():res = requests.get(url = 'http://www.baidu.com')if res.status_code == 200:return res.textraise Exceptionweb = baidu()
print(web)

这次呢还是访问百度,但是加了一个条件,可以看到哈,重试三次之后不再重试,一般用于使用账号密码登录的爬虫,有的账号一天只能登录5次,超过5次就无法登录了,

在运行程序的时候,使用retry + stop_after_attempt()简直就是用了飘柔一样的柔顺啊!!!

重试5秒后不再重试

from tenacity import retry , stop_after_attempt , stop_after_delayimport requests# 指定5s重试间隔
@retry(stop=stop_after_delay(5))
def baidu():web = requests.get(url = 'http://www.baidu.com')if web.status_code == 200:return web.textraise Exception
res = baidu()
print(res)

用|连接多个重试条件

from tenacity import retry , stop_after_attempt , stop_after_delayimport requests# 使用'|' 连接多个条件组合使用@retry(stop=stop_after_delay(5) | stop_after_attempt(3))
def baidu():web = requests.get(url = 'http://www.baidu.com')if web.status_code == 200:return web.textraise Exception
res = baidu()
print(res)

在重试前设置随机等待时间

from tenacity import retry , stop_after_attempt , stop_after_delay , wait_fixed , wait_randomimport requests# 在程序重试前设置随机等待时间
@retry(wait = wait_random(min=1,max=2))
def baidu():web = requests.get(url = 'http://www.baidu.com')if web.status_code == 200:return web.textraise Exception
res = baidu()
print(res)

按照指定数等待时间

from tenacity import retry , stop_after_attempt , stop_after_delay , wait_fixed , wait_random , wait_exponentialimport requests# 按照指定数等待时间
@retry(wait = wait_exponential(multiplier=2,min = 3,max = 100))
def baidu():web = requests.get(url = 'http://www.baidu.com')if web.status_code == 200:return web.textraise Exception
res = baidu()
print(res)

有触发条件的retry语句

from tenacity import retry ,retry_if_exception_type ,retry_if_resultimport requests# 有触发条件的retry语句@ retry(retry = retry_if_exception_type(IOError))
def fun_1():print('巴拉巴拉巴拉巴拉')raise Exceptiondef fun_2(value):return value is None@ retry(retry = retry_if_exception_type(fun_2))
def fun_3():print('滴滴滴滴滴')@ retry(retry=(retry_if_result(fun_2)|retry_if_exception_type()))
def fun_4():print('呼呼呼呼呼呼')

在retry前后增加log

from tenacity import retry , stop_after_attempt ,before_log ,after_log , before_sleep_log
import logginglogger = logging.getLogger(__name__)@ retry(stop = stop_after_attempt(3),before = before_log(logger,logging.DEBUG))
def fun_1():raise Exception('Error')@ retry(stop = stop_after_attempt(3),after = after_log(logger,logging.DEBUG))
def fun_2():raise Exception('Error')
@ retry(stop = stop_after_attempt(3),before_sleep = before_sleep_log(logger,logging.DEBUG))
def fun_3():raise Exception('Error')

就是这么easy~~~~~~

推荐阅读
平时都逛哪些技术网站?(程序员必备58个网站汇总)肝!精心整理了 50 个数据源网站!3种Python数据结构,13种创建方法,这个总结,超赞!

Python爬虫还在写重试代码?快快学习下优雅的tenacity库!相关推荐

  1. python简介怎么写-python爬虫简历怎么写

    python爬虫简历怎么写? python爬虫简历如下: 1. 基本信息 求职岗位:Python爬虫工程师(全职) 期望薪资:15000以上 姓名:xx 手机号码:xxxx 邮箱:xxxx@qq.co ...

  2. Python爬虫原理与简单示例代码

    链接 链接 爬取知乎热榜话题: 链接 BeautifulSoup的使用1: url = 'http://www.cntour.cn/'strhtml = requests.get(url)soup = ...

  3. 90%老手的都不知道,Python异常还能写得如此优雅!

    在写程序时,我们会经常碰到程序出现异常,这时候我们就不得不处理这些异常,以保证程序的健壮性. 处理异常的版本有以下几种,你通常的做法是哪种? 不负责任版本 这种情况下,不作任何处理,任由程序报错,从而 ...

  4. 【数据分析】【数据获取】【Python爬虫】快速入门+实例+代码+GIF实操

    一:爬虫认知 爬虫名称由来于蜘蛛结网,蜘蛛在一个一个的蛛网节点中等待猎物的到来.而我们的爬虫也是从网页页面的HTML资源中取出我们要的节点资源.二者过程相似,因此爬虫称之为Spider. 1.1 爬虫 ...

  5. 爬虫python代码-Python爬虫入门(01) -- 10行代码实现一个爬虫

    跟我学习Python爬虫系列开始啦.带你简单快速高效学习Python爬虫. 一.快速体验一个简单爬虫 以抓取简书首页文章标题和链接为例 简书首页 就是以上红色框内文章的标签,和这个标题对应的url链接 ...

  6. 爬虫python代码-Python爬虫教程:200行代码实现一个滑动验证码

    Python爬虫教程:教你用200行代码实现一个滑动验证码 做网络爬虫的同学肯定见过各种各样的验证码,比较高级的有滑动.点选等样式,看起来好像挺复杂的,但实际上它们的核心原理还是还是很清晰的,本文章大 ...

  7. python爬虫之多线程、多进程+代码示例

    python爬虫之多线程.多进程 使用多进程.多线程编写爬虫的代码能有效的提高爬虫爬取目标网站的效率. 很多人学习python,不知道从何学起. 很多人学习python,掌握了基本语法过后,不知道在哪 ...

  8. python爬虫代码-Python爬虫入门(01) -- 10行代码实现一个爬虫

    跟我学习Python爬虫系列开始啦.带你简单快速高效学习Python爬虫. 一.快速体验一个简单爬虫 以抓取简书首页文章标题和链接为例 简书首页 就是以上红色框内文章的标签,和这个标题对应的url链接 ...

  9. python爬虫代码-Python爬虫教程:200行代码实现一个滑动验证码

    Python爬虫教程:教你用200行代码实现一个滑动验证码 做网络爬虫的同学肯定见过各种各样的验证码,比较高级的有滑动.点选等样式,看起来好像挺复杂的,但实际上它们的核心原理还是还是很清晰的,本文章大 ...

最新文章

  1. 数据结构|-常见数据结构整理
  2. UE4全景插件Nvidia Ansel Photography
  3. Azure Bill
  4. 动态规划经典例题:乘积最大连续子数组
  5. maven 打包jar_Maven一定要会的这几个知识!
  6. NLPIR智能语义技术从采集到分析一步到位
  7. 【顶尖技术人是怎样炼成的】清华博士的模型信仰——对话阿里云 MVP陈旸
  8. mysql 主表存hash和子表的名字_【mysql】mysql分表和表分区详解
  9. 【资料】机器学习笔记的github镜像下载(github个人star数量排名175)
  10. (七)使用Docker进行人脸识别
  11. 帝国cms怎么搭建python环境_Python 库/模块的pip安装和IPython的使用
  12. 成长有三方面,其中最重要的是
  13. Python模块-decimal
  14. solidwork运行python脚本_Matlab – Solidworks 机器人建模(3)如何把URDF文件导入到Matlab...
  15. WordPress中文插件 Erphpdown vip会员+推广提成+收费下载/查看内容+前端个人中心 银联/支付宝/微信支付/财付通/贝宝paypal[更新至v9.6.1]
  16. SEGGER_RTT_printf()函数实现打印浮点、负数-示例
  17. mysql json 数组转行
  18. step7-- simatic -- PLC - MPI --
  19. 基于layui和ThinkPHP6开发的通用后台管理框架
  20. 微软 WP 手机刷机工具已恢复正常

热门文章

  1. elasticsearch与PHP版本要求
  2. jQuery遇见的转化关联数组为json的坑
  3. 服务中添加mysql服务_Windows平台下在服务中添加MySQL
  4. 微信小程序之redirectTo、switchTab和navigateTo
  5. php中如何让这段东西不显示出来,数据显示处理,该怎么处理
  6. 山西农业大学c语言答案,作业答案
  7. linux ubuntu安装教程6,64位Ubuntu下安装IE6步骤
  8. mysql 重复率高字段 索引_MySQL性能优化(二)索引优化
  9. 解决ERROR: cannot download default sources list from:https://raw.githubusercontent.com/ros/rosdistro/m
  10. oracle生成42位,Oracle HowTo:如何确定Oracle是32 Bit(位)的还是64 Bit(位)的?