访问频率组件
这个组件是用来控制单位时间内某个用户的访问次数的. 可以用在反爬虫中
基础的BaseThrottle类提供接口 接口函数为 allow_request,如果返回False则走wait
SimpleRateThrottle类给我们提供了get_cache_key接口,继承这个类要写rate(num_request, duration)多长时间内访问次数
实现原理如下代码:
class SimpleRateThrottle(BaseThrottle): def allow_request(self, request, view): if self.rate is None: return True self.key = self.get_cache_key(request, view) if self.key is None: return True self.history = self.cache.get(self.key, []) self.now = self.timer() # 原理的实现逻辑 while self.history and self.history[-1] <= self.now -self.duration: self.history.pop() if len(self.history) >= self.num_requests: return self.throttle_failure() return self.throttle_success()
题目:限制用户一分钟访问3次
代码逻辑
1.先建立一个访问记录字典,以用户ip作为键,以访问时间点作为值,作为列表 2.先判断当前时间,减去列表中的第一个时间, 1.如果时间大于60秒,说明不在一分钟之内,就把第一个值给删掉,然后把当前的时间添加到记录字典中去. 2.如果时间小于等于60秒,说明第一个值是在一分钟之内,然后再判断列表中的个数是否大于3, 如果大于等于3,则返回False,则表明频率超了,如果小于3则把当前的时间添加到记录字典中去,.返回True
mythrottle.py:
import time from rest_framework.throttling import BaseThrottle visit_record={} class MyThrottles(BaseThrottle): #继承了这个类就不用自己定义wait了 def allow_request(self,request,abc):#源码中规定必须有这个方法 visit_ip=request.META.get("REMOTE_ADDR") #得到用户进来的IP地址 ,我们可也以用BaseThrottle这个类中的get_ident(request)来获得ip地址 ctime=time.time() if visit_ip not in visit_record: visit_record[visit_ip]=[ctime] return True if len( visit_record[visit_ip])<3: #修改这里就可以修改登录次数 visit_record[visit_ip].insert(0,ctime) return True if (ctime-visit_record[visit_ip][-1])>60: visit_record[visit_ip].insert(0, ctime) visit_record[visit_ip].pop() print(visit_record) return Trueviews.py return False
局部频率限制
views.py:
class BookViewSet(viewsets.ModelViewSet): # authentication_classes = [Authentication,] # permission_classes=[SvipPermissions] throttle_classes =[MyThrottles] queryset = Book.objects.all() serializer_class = Bookserializers
全局限制:
settings.py:
REST_FRAMEWORK={"DEFAULT_THROTTLE_CLASSES":["api_demo.service.mythrottle.MyThrottles"], }
使用默认SimpleRateThrottle类
rest_framwork内置提供了几个频率限制类,基类就是BaseThrottle,
我们现在使用SimpleRateThrottle这个类来写频率限制组件
setting .py:
REST_FRAMEWORK = { "DEFAULT_THROTTLE_CLASSES": ["api_demo.service.mythrottle.MyThrottles"], "DEFAULT_THROTTLE_RATES": { "visit_rate": "5/m", #限制登录次数 } }
mythrottle.py:
import time from rest_framework.throttling import BaseThrottle,SimpleRateThrottle class MyThrottles(SimpleRateThrottle): #SimpleRateThrottle 这个类可以帮我们任意限定登录次数 scope = "visit_rate" #这里定义setting中的DEFAULT_THROTTLE_RATES对应的字典键值 def get_cache_key(self, request, view): return self.get_ident(request) #计算次数时以什么为键来记录登录时间,我们是以IP地址