反爬虫策略手把手教你使用FastAPI来限制接口的访问速率

击上方“Python爬虫与数据挖掘”,进行关注

回复“书籍”即可获赠Python从入门到进阶共10本电子书

秋风吹不尽,总是玉关情。 

在网络爬虫的过程中,我们都会遇到各种各样的反爬虫,封禁IP和账号,设置验证码,前端加密,浏览器指纹,甚至输出假数据来等等都是可能出现的反爬手段,这些我们今天一个也不会谈及,而是谈谈一种叫访问速率限制的手段。


对于服务端而言,有时候会碰到这么一个场景:某个接口需要在某个时间段内设置最高的访问次数来降低服务器的压力,比如之前用的某度的一些接口,一分钟内访问次数过高就会返回失败,等上个2分钟就又可以返回了。目的就是为了防止开发人员或者爬虫,甚至是恶意请求对服务器无限制的访问,降低服务器开支,因为一般的用户的请求是不会这么频繁的

Ratelimiter

python 中使用 Ratelimiter 来限制某方法的调用次数,用法如下

import time
from ratelimiter import RateLimiter

def limited(until):
    duration = int(round(until - time.time()))
    print('Rate limited, sleeping for {:d} seconds'.format(duration))
# 3秒之内只能访问2次
rate_limiter = RateLimiter(max_calls=2, period=3, callback=limited)

for i in range(3):
    with rate_limiter:
        print('Iteration', i)

输出结果如下

Iteration 0
Iteration 1
Rate limited, sleeping for 3 seconds
Iteration 2

看到程序如期打印, callback 指定了超出指定次数是回调方法 

达到了预期的要求

asyncio 异步中的使用

import asyncio
import time

from ratelimiter import RateLimiter

async def limited(until):
    duration = int(round(until - time.time()))
    print('Rate limited, sleeping for {:d} seconds'.format(duration))

async def coro():
    rate_limiter = RateLimiter(max_calls=2, period=3, callback=limited)
    for i in range(3):
        async with rate_limiter:
            print('Iteration', i)

loop = asyncio.get_event_loop()
loop.run_until_complete(coro())

执行结果是一致的, 在一般的 python 方法里面用 Ratelimiter 是没有问题的

Slowapi

对于网络请求的访问速率限制,我建议使用 Slowapi 库,Slowapi相对灵活易用,不必考虑更多的因素。在 fastapi 和 flask 中使用也是得心应手,当然flask框架也有第三方扩展,这个自不必说,django也有自带的限制访问速率的库,而 fastapi 相对比较新,扩展库相对匮乏,在一个偶然的机会看到 Slowapi 的源码, 这是一个非常不错的选择,如果有机会,我会把它封装成 fastapi 框架的另一个插件,继成更多的功能,名字可以是 fastapi-slowapi 之类的

来看看具体的用法

# -*- coding: utf-8 -*
# @Time : 2020/11/11 11:09
from fastapi import FastAPI
from slowapi import Limiter, _rate_limit_exceeded_handler
from slowapi.errors import RateLimitExceeded
from slowapi.util import get_remote_address

# 初始化 slowapi,注册进 fastapi
limiter = Limiter(key_func=get_remote_address)
FastAPI().state.limiter = limiter
FastAPI().add_exception_handler(RateLimitExceeded, _rate_limit_exceeded_handler)

具体调用方法

# -*- coding: utf-8 -*
# @Time : 2020/11/11 11:09

# 一小时内只能调用该接口 4 次
@limiter.limit("4/hour")
async def startSpider(*, request: Request, d_obj: dict):
    if request.method == "POST":
        statusDict = get_spider_status(shopId=d_obj.get("shopId"))
        if not statusDict.get("data"):
            return resp_422(message='程序正在抓取中,请勿重复调度')
        try:
            result = all_run(d_obj.get("shopId"))
            return result
        except:
            return resp_401()
    return "这是一个GET请求"

这是我写的一个用于限制爬虫调度的一个方法,如果这个爬虫接口一小时中调度超过 4 次就返回调度超过指定次数的结果,当然代码中的 hour 也可以是 minute 或者 second,使用相对简单,大家可以一试并自行扩展

具体作用就是为了限制某接口在单位时间内被调用的次数,对于后端开发者来说可以减少对服务器的访问压力,而对于爬虫工程师而言,这也是从某种程度上保护我方数据的一种策略。

需要具体代码的小伙伴可以后台回复关键字:限制爬虫,进行获取。

------------------- End -------------------

往期精彩文章推荐:

欢迎大家点赞,留言,转发,转载,感谢大家的相伴与支持

想加入Python学习群请在后台回复【入群

万水千山总是情,点个【在看】行不行

/今日留言主题/

随便说一两句吧~~

  • 7
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 10
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值