前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python爬虫还在写重试代码?快快学习下优雅的tenacity库!

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

作者头像
小小詹同学
发布2021-01-22 10:36:02
6140
发布2021-01-22 10:36:02
举报
文章被收录于专栏:小詹同学小詹同学

前言

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

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

代码语言:javascript
复制
pip install tenacity

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

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

代码语言:javascript
复制
import tenacity

import requests

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

res = baidu()
print(res)

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

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

代码语言:javascript
复制
from tenacity import retry , stop_after_attempt , stop_after_delay , wait_fixed

import requests

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

设置停止的基本条件

只重试3次

代码语言:javascript
复制
from tenacity import retry,stop_after_attempt

import 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.text
    raise Exception

web = baidu()
print(web)

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

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

重试5秒后不再重试

代码语言:javascript
复制
from tenacity import retry , stop_after_attempt , stop_after_delay

import 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.text
    raise Exception
res = baidu()
print(res)

用|连接多个重试条件

代码语言:javascript
复制
from tenacity import retry , stop_after_attempt , stop_after_delay

import 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.text
    raise Exception
res = baidu()
print(res)

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

代码语言:javascript
复制
from tenacity import retry , stop_after_attempt , stop_after_delay , wait_fixed , wait_random

import 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.text
    raise Exception
res = baidu()
print(res)

按照指定数等待时间

代码语言:javascript
复制
from tenacity import retry , stop_after_attempt , stop_after_delay , wait_fixed , wait_random , wait_exponential

import 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.text
    raise Exception
res = baidu()
print(res)

有触发条件的retry语句

代码语言:javascript
复制
from tenacity import retry ,retry_if_exception_type ,retry_if_result

import requests

# 有触发条件的retry语句

@ retry(retry = retry_if_exception_type(IOError))
def fun_1():
    print('巴拉巴拉巴拉巴拉')
    raise Exception

def 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

代码语言:javascript
复制
from tenacity import retry , stop_after_attempt ,before_log ,after_log , before_sleep_log
import logging

logger = 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~~~~~~

代码语言:javascript
复制
代码语言:javascript
复制
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-01-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 小詹学Python 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 无条件重试,重试之间无间隔
  • 设置停止的基本条件
    • 只重试3次
      • 重试5秒后不再重试
        • 用|连接多个重试条件
        • 在重试前设置随机等待时间
        • 按照指定数等待时间
        • 有触发条件的retry语句
        • 在retry前后增加log
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档