python反反爬虫技术限制连续请求时间处理
作者:Python编程学习圈 发布时间:2023-08-27 13:53:04
前言
一般的反爬措施是在多次请求之间增加随机的间隔时间,即设置一定的延时。但如果请求后存在缓存,就可以省略设置延迟,这样一定程度地缩短了爬虫程序的耗时。
下面利用requests_cache实现模拟浏览器缓存行为来访问网站,具体逻辑如下:存在缓存,就直接走,不存在缓存,就停一下再走
示例代码
用勾子函数根据缓存行为设置访问时间
import requests_cacheimport timerequests_cache.install_cache()
#默认按照浏览器的缓存进行
requests_cache.clear()
def make_throttle_hook(timeout=0.1):
def hook(response, *args, **kwargs):
print(response.text)
# 判断没有缓存时就添加延时
if not getattr(response, 'from_cache', False):
print(f'Wait {timeout} s!')
time.sleep(timeout)
else:
print(f'exists cache: {response.from_cache}')
return response
return hookif __name__ == '__main__':
requests_cache.install_cache()
requests_cache.clear()
session = requests_cache.CachedSession()
# 创建缓存会话
session.hooks = {'response': make_throttle_hook(2)}
# 配置钩子函数
print('first requests'.center(50,'*'))
session.get('http://httpbin.org/get')
print('second requests'.center(50,'*'))
session.get('http://httpbin.org/get')
有关requests_cache的更多用法,参考下面requests_cache说明
爬虫相关库
1. 爬虫常用的测试网站:httpbin.org
httpbin.org 这个网站能测试 HTTP 请求和响应的各种信息,比如 cookie、ip、headers 和登录验证等,且支持 GET、POST 等多种方法,对 web 开发和测试很有帮助。它用 Python + Flask 编写,是一个开源项目。
2. requests-cache
requests-cache,是 requests 库的一个扩展包,利用它可以非常方便地实现请求的缓存,直接得到对应的爬取结果。
作用和使用场景
1.在爬取过程中,它可以根据浏览器的缓存机制来选择缓存内容。从请求行为上看与浏览器更加相似,起到反反爬的效果。
2.另外,还可以自定义缓存机制,在爬虫项目中,优化性能。
requests-cache库只能对requests的请求实现缓存功能,而且requests要以session方式进行请求。单独的requests.get、requests.post 不能被缓存。
requests
使用方法
安装:
$ pip install requests-cache
与普通的代码比较
在爬取一个域名下的多个url时,使用requests.session.get或requests.session.post会比单纯的requests.get、requests.post更高效。因为它只建立了一个会话,并在上面做多次请求。同时还支持登录信息cookie等的传递。
下面比较一下缓存代码的写法 没有缓存的代码:
普通的requests session爬取
import requests
import time
start = time.time()
session = requests.Session()
for i in range(10):
session.get('http://httpbin.org/delay/1')
print(f'Finished {i + 1} requests')
end = time.time()
print('Cost time', end - start)
该代码是访问了httpbin.org网站,该网站会解析delay/1,在1秒后返回。
有缓存的代码:
带缓存的requests session爬取
import requests_cache #pip install requests_cache
import time
start = time.time()
session = requests_cache.CachedSession('demo_cache')
for i in range(10):
session.get('http://httpbin.org/delay/1')
print(f'Finished {i + 1} requests')
end = time.time()
print('Cost time', end - start)
为原有代码微创式添加缓存功能
只需要添加一句requests_cache.install_cache('demo_cache')即可。
微创式添加缓存功能
import requests_cache #pip install requests_cache
requests_cache.install_cache('demo_cache')#demo_cache.sqlite 做缓存
import requests
import time
start = time.time()
session = requests.Session()
for i in range(10):
session.get('http://httpbin.org/delay/1')
print(f'Finished {i + 1} requests')
end = time.time()
print('Cost time', end - start)
缓存的清空和识别
如果需要清空缓存,可以调用:requests_cache.clear() # 清空缓存代码
通过res.from_cache可以判断该值是否是缓存值:
import requests_cache
import requests
requests_cache.install_cache() # 设置缓存
requests_cache.clear() # 清空缓存
url = 'http://httpbin.org/get'
res = requests.get(url)
print(f'cache exists: {res.from_cache}')
# cache exists: False # 不存在缓存
res = requests.get(url)
print(f'exists cache: {res.from_cache}')
# exists cache: True # 存在缓存
自定义设置缓存的形式
requests_cache.install_cache默认的方式是与浏览器的缓存行为一致的。如果要自定义可以先了解该函数的参数:
requests_cache.install_cache定义
requests_cache.install_cache(
cache_name='cache',
backend=None,
expire_after=None,
allowable_codes=(200,),
allowable_methods=('GET',),
filter_fn=<
function <lambda> at 0x11c927f80>,
session_factory=<
class 'requests_cache.core.CachedSession'>,
**backend_options,)
该参数说明如下: - cache_name:缓存文件名称。
backend:设置缓存的存储机制,默认使用sqlite进行存储。
支持四种不同的存储机制,分别为memory、sqlite、mongoDB、redis。在设置存储机制为mongoDB、redis时需要提前安装对应的模块。pip install pymongo; pip install redies。memory:以字典的形式将缓存存储在内存当中,程序运行完以后缓存将被销毁
sqlite:将缓存存储在sqlite数据库中
mongoDB:将缓存存储在mongoDB数据库中
redis:将缓存存储在redis中
expire_after:设置缓存的有效时间,默认永久有效。
allowable_codes:设置状态码。
allowable_methods:设置请求方式,默认get,表示只有get请求才可以生成缓存。
session_factory:设置缓存执行的对象,需要实现CachedSession类。
**backend_options:如果缓存的存储方式为sqlit、mongo、redis数据库,该参数表示设置数据库的连接方式。
自定义设置缓存的例子1:设置缓存文件类型
设置缓存文件类型的代码如下:
#设置缓存:任选其一
requests_cache.install_cache('demo_cache')#demo_cache.sqlite 做缓存
#demo_cache文件夹做缓存,删除及表示清空缓存
requests_cache.install_cache('demo_cache', backend='filesystem')
#缓存文件夹便会使用系统的临时目录,而不会在代码区创建缓存文件夹。
requests_cache.install_cache('demo_cache', backend='filesystem', use_temp=True)
#缓存文件夹便会使用系统的专用缓存文件夹,而不会在代码区创建缓存文件夹
requests_cache.install_cache('demo_cache', backend='filesystem', use_cache_dir=True)
#Redis ,需要安装redis-py pip install redies
backend = requests_cache.RedisCache(host='localhost', port=6379)
requests_cache.install_cache('demo_cache', backend=backend)
其他不同格式:
MongoDB 安装pymongo pip install pymongo;
调用requests_cache.MongoCache 保存为’mongodb’
gridfs 安装pymongo
调用requests_cache.GridFSCache 保存为’gridfs’
DynamoDB boto3 调用requests_cache.DynamoDbCache 保存为’dynamodb’
Memory 以字典的形式将缓存存储在内存当中,程序运行完以后缓存将被销毁 调用requests_cache.BaseCache 保存为’memory’
自定义设置缓存的例子2:设置缓存保存内容
具体例子代码如下:
import time
import requests
import requests_cache
#只缓存post
requests_cache.install_cache('demo_cache2', allowable_methods=['POST'])
#只缓存200返回值的请求
requests_cache.install_cache('demo_cache2', allowable_codes=(200,))
只缓存200返回值的请求
设置缓存的过期时间:
#site1.com 的内容就会缓存 30 秒,site2.com/static 的内容就永远不会过期
urls_expire_after = {'*.site1.com': 30, 'site2.com/static': -1}
requests_cache.install_cache(
'demo_cache2', urls_expire_after=urls_expire_after)
在响应头中,浏览器会根据cache_control参数来确定是否保存缓存,在设置requests_cache缓存时,可以对cache_control参数设置,使其保存浏览器不需要保存的内容。
# 保存头中,cache_control设为不保存的请求
requests_cache.install_cache('demo_cache3', cache_control=True)
start = time.time()
session = requests.Session()
for i in range(10):
session.get('http://httpbin.org/delay/1')
print(f'Finished {i + 1} requests')
end = time.time()
print('Cost time for get', end - start)
start = time.time()
for i in range(10):
session.post('http://httpbin.org/delay/1')
print(f'Finished {i + 1} requests')
end = time.time()
print('Cost time for post', end - start)
在 Request Headers 里面加上了 Cache-Control 为 no-store,这样的话,即使我们声明了缓存那也不会生效
session.get('http://httpbin.org/delay/1',
headers={
'Cache-Control': 'no-store'
}
)
来源:https://juejin.cn/post/7101862779136507941
猜你喜欢
- 目录 一、环境配置 二、ASP对Excel的基本操作 三、ASP操作Excel生成数据表 四、ASP操作Excel生成Chart图 五、服务
- 在做我的友情链接批量检查工具过程中,碰到一些情况,就是对方网页会用gzip压缩。用gzip压缩的好处是,能压缩网页大小,加快网页的浏览速度,
- 本文讨论 MySQL 的备份和恢复机制,以及如何维护数据表,包括最主要的两种表类型:MyISAM 和 Innodb,文中设计的 MySQL
- 下面是IN条件运算符的SQL语句:SELECT column1, SUM(column2) FROM&nbs
- 在MySQL数据库中导出整个数据库:1.导出整个数据库mysqldump -u 用户名 -p 数据库名 > 导出的文件名mysqldu
- 大家知道直接使用ASP是不能够重启服务器的,这时我们需要制作一个组件来实现功能,ASP通过这个组件调用系统API,然后按照不同的重启和关机方
- 随着jQuery、Mootools、prototype等知名的JavaScript框架的应用变的越来越强大,浏览器对最新版本CSS属性的支持
- 除了在 Error 对象和 Errors 集合中说明的提供者错误之外,ADO 本身也将错误返回到运行时环境的异常处理机制之中。使用
- 这些导航菜单来自于Dribbble网站,出自于世界各地的优秀设计师之手,涵盖了各种不同的风格,个个都非常精美。这里我将这些导航菜单展示出来,
- 是否曾经有过这样的经历:把一个元素置于另一个元素之上,而希望下面的那个元素成为可点击的?现在,利用css的pointer-events属性即
- shift:删除原数组第一项,并返回删除元素的值;如果数组为空则返回undefined var a = [1,2,3,4,5]; var b
- 1、简述asp的6个内置对象和其功能答案 : session ,server ,response,request,objectcontext
- 反射指的是运行时动态的获取变量的相关信息1. reflect 包类型是变量,类别是常量reflect.TypeOf,获取变量的类型,返回re
- 我们已经知道Application和Session对象的OnStart、OnEnd事件的脚本,都必须是在 Global.asa&n
- 许多网站缺乏针对性和友好的导航设计,难以找到连接到相关网页的路径,也没有提供有助于让访客/用户找到所需信息的帮助,用户体验非常糟糕。本期薯片
- 简单的说,一个数据库管理系统应该的提供的基本服务有两种:1.数据访问。对每个数据库管理系,数据访问服务都包含一下几种(1)插入--向数据库中
- asp上传的时候出现这种 错误:Server 对象 错误 'ASP 0177 800401f3'Server.CreateO
- 如下所示:#coding utf-8a=0.001 #定义收敛步长xd=1 #定义寻找步
- RedHat 9.0下自带的mysql rpm包为mysql-3.23.54a-11.i386.rpm,如果在你安装操作系统时没有安装mys
- 因为主键可以唯一标识某一行记录,所以可以确保执行数据更新、删除的时候不会出现张冠李戴的错误。当然,其它字段可以辅助我们在执行这些操作时消除共