Requests-Cache模块是requests模块的一个扩展功能,用于为requests模块提供持久化缓存支持。如果requests模块向一个URL发送重复请求时,Requests-Cache模块将会自动判断当前的网络请求时否产生了缓存。如果已经产生了缓存,就会从缓存中读取数据作为响应内容。如果没有缓存就会向服务器发送网络请求,获取服务器所返回的响应内容。使用Requests-Cache模块可以减少网络资源避免重复请求的次数,这样可以变相地躲避一些反爬机制
1、安装
pip install requests-cache
说明:
无论是否使用了Anaconda,都需要单独安装Requests-Cache模块,因为Anaconda中并不包含该模块。
1、install_cache()
格式:
install_cache(cache_name='cache',backend=None,expire_after=None,
allowable_codes=(200,),allowable_methods=('GET',),session_factory=<class 'requests_cache.core.CachedSession'>,**backend_options)
参数:
cache_name: 缓存文件的名称,默认为cache
backend: 表示设置缓存的存储机制,默认为None,表示默认使用sqlite进行存储
expire_after: 表示设置缓存的有效时间,默认为None,表示永久有效
allowable_codes: 设置状态码,默认为200
allowable_methods: 设置请求方式,默认为GET,表示只有GET请求才可以生成缓存
session_factory: 表示设置缓存执行的对象,需要实现CachedSesion类。
**backend_options: 如果缓存的存储方式为sqlite,mongo,redis数据库,该参数设置数据库的链接方式
说 明
Requests-Cache模块支持4种不同的存储机制,分别为money、sqlite、mongoDB以及redid,具体说明如下:
§ memory: 以字典的形式将缓存存储在内存当中,程序运行完后缓存将被销毁
§ sqlite: 将缓存存储在sqlite数据库中
§ mongoDB:将缓存存储在mongoDB数据库中
§ redis: 将缓存存储在redis数据库当中
使用Requests-Cache模块指定缓存不同的存储机制时,只需要为install_cache()函数中backend参数赋值即可,设置方式如下:
# 导入Requests_Cache模块
import requests_cache
# 设置缓存为内存的存储机制
requests_cache.install_cache(backend='memory')
# 设置缓存为sqlite数据库的存储机制
requests_cache.install_cache(backend='sqlite')
# 设置缓存为mongoDB数据库的存储机制
requests_cache.install_cache(backend='mongoDB')
# 设置缓存为redis数据库的存储机制
requests_cache.install_cache(backend='redis')
案例:
import requests_cache
import requests
requests_cache.install_cache() # 设置缓存
# 其他缓存方式
backend = requests_cache.RedisCache(host='127.0.0.1',port=6379)
# backend = requests_cache.MongoCache()
requests_cache.install_cache(backend=backend)
requests_cache.clear() # 清理缓存
url = 'http://httpbin.org/get'
response = requests.get(url)
print('是否设置了缓存:',response.from_cache)
response2 = requests.get(url)
print('是否使用了缓存:',response2.from_cache)
针对反爬措施,在多次请求中设置延时是不错的选择。但是如果在第一次请求后生成了缓存,那么第二次请求时就无需设置延时,为此Requests-Cache模块可以使用自定义钩子函数的方式,合理判断是否需要设置延时操作。示例代码如下:
import requests_cache
import time
# 定义钩子函数
def make_throttle_hook(timeout=0.1):
def book(response,*args,**kwargs):
print(response.text)
# 判断没有缓存时就添加延时
if not getattr(response,'from_cache',False):
print('等待',timeout,'秒')
time.sleep(timeout)
else:
print('是否存在请求缓存:',response.from_cache)
return response
return book
if __name__ == '__main__':
requests_cache.install_cache() # 创建缓存
requests_cache.clear() # 清理缓存
s = requests_cache.CachedSession() # 创建缓存会话
s.hooks = {'response':make_throttle_hook(2)} # 配置钩子函数
s.get('http://httpbin.org/get')
s.get('http://httpbin.org/get')
程序运行结果:
第一次运行结果:
{
"args": {},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Host": "httpbin.org",
"User-Agent": "python-requests/2.27.1",
"X-Amzn-Trace-Id": "Root=1-61f5e91a-5c923abe41da544561b5f400"
},
"origin": "139.209.219.102",
"url": "http://httpbin.org/get"
}
等待2秒,第二次请求结果
{
"args": {},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Host": "httpbin.org",
"User-Agent": "python-requests/2.27.1",
"X-Amzn-Trace-Id": "Root=1-61f5e91a-5c923abe41da544561b5f400"
},
"origin": "139.209.219.102",
"url": "http://httpbin.org/get"
}
二次请求存在缓存
是否存在请求缓存! True
从以上的运行结果看,通过配置钩子函数可以实现:在第一次请求时,因为没有请求缓存所以执行了2秒等待延时;第二次请求时则没有执行2秒 延时,并输出是否存在请求缓存行为True。