python 爬虫的重试机制

python 爬虫的重试机制(二)

0 背景

在之前我们提到了python requests自带的重试机制, 可以让网络请求在超时或者特定的响应码进行重试, 可以增加我们抓取请求成功的机会.

那在面对更复杂的情况时, 我们应该如何进行重试呢? 比如, 当我们判断response.text 存在no data时就重试, 应该如何设置重试条件呢?

我们可以使用一个第三方的重试框架retrying.

retrying 是一个 Python 库,用于简化在失败时重试函数调用的过程。这个库真的是非常滴有用,尤其是在处理网络请求、远程服务调用或任何可能因暂时性问题(如网络延迟、服务不可用等)而失败的操作时。

下面是 retrying 的一些主要特点和优点:

  1. 灵活的重试策略:retrying 允许我们自定义重试策略,例如设置最大重试次数、重试等待时间等。

  2. 装饰器支持:它通过装饰器提供了一种简单的方式来应用重试逻辑。我们只需将装饰器添加到需要重试的函数上。

  3. 条件重试:retrying 支持基于异常类型或返回值的条件重试。比如,我们可以指定仅当特定类型的异常被抛出时才重试。

  4. 等待策略:支持多种等待策略,如固定时间等待、指数退避等待等,这有助于更有效地处理重试。

  5. 停止策略:我们可以定义何时停止重试,如达到最大尝试次数或超过指定的时间限制。

  6. 调试和日志记录:retrying 还支持调试和日志记录,这有助于我们开发和调试重试逻辑。

  7. 简单易用:最后但同样重要的是,retrying 非常简单易用,它可以轻松集成到我们现有的 Python 项目中。

1 使用

retrying是一个第三方模块, 需要额外安装:

pip install retrying

简要说明以下这个包的一些参数, 该包是通过装饰器对函数进行重试的. 一些有条件的参数, 写在装饰器函数retry()

retry                                            # 不加参数表示无限重试
retry(wait_fixed = 100)                          # 设置重试间隔时长,单位:ms,1000ms = 1s
retry(wait_random_min=100,wait_random_max=200)   # 随机重试间隔,将在100ms - 200ms内
retry(stop_max_attempt_number = 4)               # 最大重试次数,超过后正常抛出异常
retry(stop_max_delay=1)                          # 最大延迟时长,1ms内未满足条件则抛出异常
retry(retry_on_exception = user_define_function)           # 当发生指定异常时会执行函数
retry(retry_on_result=user_define_function)                # 每次都会执行函数,当返回返回True就重试,否则异常退出

我们先模拟一个简单的爬虫, 当然, 重试机制不一定只在爬虫上, 可以应用到很多场景, 爬虫请求往往会收到网络 | 反爬等一些影响, 导致一次请求不会成功, 因此, 重试机制可以有效避免爬虫请求出现异常的情况.

我们先模拟一个简单的爬虫, 并且会出现了错误的爬虫. 待会会用到重试模块, 有条件的重试可以帮助爬虫提升抓取能力.

from retrying import retry
import time
import requests


def spider():
    print('spider engine start work.')
    time.sleep(2)
    raise requests.exceptions.ReadTimeout('超时请求错误')


if __name__ == '__main__':
    spider()

1 重试次数

@retry()
def spider():
    print('spider engine start work.')
    time.sleep(2)
    raise requests.exceptions.ReadTimeout('超时请求错误')

出现异常就会无限重试, 以上的结果当然是无限输出spider engine start work., 在爬虫当中, 这是不可取的.

stop_max_attempt_number

@retry(stop_max_attempt_number=5)
def spider():
    print('spider engine start work.')
    time.sleep(2)
    raise requests.exceptions.ReadTimeout('超时请求错误')

使用stop_max_attempt_number参数设置最大重试次数, 在爬虫引擎中, 有时候因为因为网络或代理IP失效等突然的原因导致请求失败, 设置最大重试次数, 可以减少这种临时的问题.

2 重试时间

stop_max_delay

@retry(stop_max_delay=5000)
def spider():
    print('spider engine start work.')
    time.sleep(10)
    raise requests.exceptions.ReadTimeout('超时请求错误')

这个我其实有点难以理解的, 后面我多去测试了几次: 使用stop_max_delay参数设置最大的重试时间, 这个是一个总的整个的所有的重试运行的时间, 如果出现了异常, 此时就需要重试, 正常会无限运行, 但是通过stop_max_delay当该函数运行超过5000毫秒的时候(上面的例子), 就不再重试了, 这样就可以在异常发生后及时处理, 也可以减少资源占用.

注意, 这个参数值的单位是毫秒.

wait_random_min & wait_random_max

@retry(wait_random_min=1000, wait_random_max=5000)
def spider():
    print(f'{time.time()} spider engine start work.')
    time.sleep(3)
    print(f'{time.time()} spider engine now working.')
    raise requests.exceptions.ReadTimeout('超时请求错误')

使用wait_random_min & wait_random_max参数可以出现异常后, 指定隔随机毫秒再运行, 这不就是为爬虫定制的参数吗!

wait_fixed

@retry(wait_fixed=5000)
def spider():
    print('spider engine start work.')
    time.sleep(2)
    print('spider engine now working.')
    raise requests.exceptions.ReadTimeout('超时请求错误')

使用wait_fixed参数时, 可以让函数出现异常时, 在特定时间后, 再继续运行, 在爬虫当时, 可以避免一些因抓取过快导致的爬虫问题, 这个参数比随机时间规律些.

3 异常的额外处理

stop_func

def get_now():
    return datetime.now().strftime("%H:%M:%S")


def send_msg_to_wechat():
    ...


def error_func(attempts, delay):
    print(f'{attempts=}, {delay=} ')
    if attempts > 3:
        send_msg_to_wechat()
    return attempts > 3


@retry(stop_func=error_func)
def spider():
    print(f'{get_now()} spider engine start work.')
    time.sleep(3)
    print(f'{get_now()} spider engine now working.')
    raise requests.exceptions.ReadTimeout('超时请求错误')

这里, 使用stop_func参数, 可以在当函数出现异常时, 交给其他函数处理. 比如, 当我的爬虫出现错误时而且错误次数出现参数时, 我就将异常情况发送到微信, 并且停止运行, stop_func接收了一个异常处理函数, 在上面的例子我指定了error_func, error_func接受两个参数, attempts表示重试运行的次数, delay表示重试期间运行的时间(毫秒).

2 关于

使用 retrying,可以让我们更容易地编写更健壮和牛X稳定的代码,特别是在处理不稳定或不确定环境时。所以我们可以试试这个框包。

感兴趣的小伙伴,赠送全套Python学习资料,包含面试题、简历资料等具体看下方。

一、Python所有方向的学习路线

Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照下面的知识点去找对应的学习资源,保证自己学得较为全面。

img
img

二、Python必备开发工具

工具都帮大家整理好了,安装就可直接上手!img

三、最新Python学习笔记

当我学到一定基础,有自己的理解能力的时候,会去阅读一些前辈整理的书籍或者手写的笔记资料,这些笔记详细记载了他们对一些技术点的理解,这些理解是比较独到,可以学到不一样的思路。

img

四、Python视频合集

观看全面零基础学习视频,看视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。

img

五、实战案例

纸上得来终觉浅,要学会跟着视频一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。

img

六、面试宝典

在这里插入图片描述

在这里插入图片描述

简历模板在这里插入图片描述
若有侵权,请联系删除
  • 19
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值