0


Python3,此神器,让爬取速率提升10倍。

让爬取速率提升10倍的神器

1、引言

小屌丝:有没有能提升 爬取速率的方法,
小鱼:嗯,提升方法有好多种,例如 多线程、装饰器,都可以啊
小屌丝:嗯,那有没有其他的方法呢?
小鱼:额,容我想一下,
在这里插入图片描述
小鱼:嘿~ 想到了
小屌丝:那是啥?
小鱼:requests_cache
在这里插入图片描述

此时,小屌丝的表情

2、requests_cache

2.1 介绍

requests_cache是 requests 库的一个扩展包,利用它我们可以非常方便地实现请求的缓存,直接得到对应的爬取结果。

2.2 安装

老规矩, pip 方式安装:

  1. pip install requests-cache

其他方式安装:

《Python3,选择Python自动安装第三方库,从此跟pip说拜拜!!》
《Python3:我低调的只用一行代码,就导入Python所有库!!》

安装完,我们就来看看它的用法。

2.3 代码实例

2.3.1 CachedSession 方法

1、requests默认请求
为了能体现出它的速度,我们先写一个默认请求

代码展示

  1. # -*- coding:utf-8 -*-# @Time : 2022-03-18# @Author : carl_DJ'''
  2. requests 方法请求
  3. '''import requests
  4. import time
  5. #开始时间
  6. start = time.time()#session
  7. session = requests.session()#循环爬取,10次for i inrange(10):
  8. session.get('http://httpbin.org/delay/2')print(f'Finish{i + 1} requests')
  9. end = time.time()print('Cost time', end - start)

运行结果

  1. Finish2 requests
  2. Finish3 requests
  3. Finish4 requests
  4. Finish5 requests
  5. Finish6 requests
  6. Finish7 requests
  7. Finish8 requests
  8. Finish9 requests
  9. Finish10 requests
  10. Cost time 24.35784935951233
  11. Process finished with exit code 0

我们可以看到 花费了24+秒

那么,我们使用CachedSession 方法来看看,能不能提速
2、CachedSession 方法

代码展示

  1. # -*- coding:utf-8 -*-# @Time : 2022-03-18# @Author : carl_DJimport requests_cache
  2. import time
  3. start = time.time()#CachedSession方法,在本地生成 demo_cache.sqlite
  4. session = requests_cache.CachedSession('demo_cache')for i inrange(10):
  5. session.get('http://httpbin.org/delay/2')print(f'Finish{i + 1} requests')
  6. end = time.time()print('Cost time', end -start)

运行结果

  1. Finish1 requests
  2. Finish2 requests
  3. Finish3 requests
  4. Finish4 requests
  5. Finish5 requests
  6. Finish6 requests
  7. Finish7 requests
  8. Finish8 requests
  9. Finish9 requests
  10. Finish10 requests
  11. Cost time 8.624990701675415
  12. Process finished with exit code 0

本地生成demo_cache.sqlite数据库
在这里插入图片描述
文件的内容,我们看下
在这里插入图片描述
我们可以可以看到,这个 key-value 记录中的 key 是一个 hash 值,value 是一个 Blob 对象,里面的内容就是 Response 的结果。

可以猜到,每次请求都会有一个对应的 key 生成,然后 requests-cache 把对应的结果存储到了 SQLite 数据库中了,后续的请求和第一次请求的 URL 是一样的,经过一些计算它们的 key 也都是一样的,所以后续 2-10 请求就立马返回了。

是的,利用这个机制,我们就可以跳过很多重复请求了,大大节省爬取时间。

2.3.2 install_cache方法

1、Patch 写法
当然,我们还有另一个方法,在不修改原有的代码请求方式,
追加一个方法,来实现爬取速率的提升。

代码展示

  1. # -*- coding:utf-8 -*-# @Time : 2022-03-18# @Author : carl_DJimport requests
  2. import requests_cache
  3. import time
  4. #调用requests_cache.install_cache方法
  5. requests_cache.install_cache('demo_path_cache')
  6. start = time.time()
  7. session = requests.session()for i inrange(10):
  8. session.get('http://httpbin.org/delay/2')print(f'Finish{i + 1} requests')
  9. end = time.time()print('Cost time', end -start)

运行结果

  1. Finish1 requests
  2. Finish2 requests
  3. Finish3 requests
  4. Finish4 requests
  5. Finish5 requests
  6. Finish6 requests
  7. Finish7 requests
  8. Finish8 requests
  9. Finish9 requests
  10. Finish10 requests
  11. Cost time 7.516860723495483
  12. Process finished with exit code 0

生成文件
在这里插入图片描述

2、修改配置
前两个demo,requests-cache 默认使用了 SQLite 作为缓存对象,
而我们这次,使用filesystem 作为缓存对象

代码展示

  1. # -*- coding:utf-8 -*-# @Time : 2022-03-18# @Author : carl_DJimport requests
  2. import requests_cache
  3. import time
  4. #使用filesystem作为缓存对象
  5. requests_cache.install_cache('demo_file_cache', backend='filesystem')
  6. start = time.time()
  7. session = requests.session()for i inrange(10):
  8. session.get('http://httpbin.org/delay/2')print(f'Finish{i + 1} requests')
  9. end = time.time()print('Cost time', end -start)

运行结果
在这里插入图片描述
在这里插入图片描述
其他后端有:
[‘dynamodb’, ‘filesystem’, ‘gridfs’, ‘memory’, ‘mongodb’, ‘redis’, ‘sqlite’]

具体的差异,我们来看下
BackendClassAliasDependenciesSQLiteSQLiteCachesqliteRedisRedisCacheredisredis-pyMongoDBMongoCachemongodbpymongoGridFSGridFSCachegridfspymongoDynamoDBDynamoDbCachedynamodbboto3FilesystemFileCachefilesystemMemoryBaseCachememory
如果使用redis

  1. backend = requests_cache.RedisCache(host='localhost', port=6379)
  2. requests_cache.install_cache('demo_redis_cache', backend=backend)

3、只对某一个请求进行缓存

  1. # -*- coding:utf-8 -*-# @Time : 2022-03-18# @Author : carl_DJimport time
  2. import requests
  3. import requests_cache
  4. #allowable_methods 方式,只对post请求进行缓存
  5. requests_cache.install_cache('demo_post_cache', allowable_methods=['POST'])
  6. start = time.time()
  7. session = requests.Session()for i inrange(10):
  8. session.get('http://httpbin.org/delay/2')print(f'Finished {i + 1} requests')
  9. end = time.time()print('Cost time for get', end - start)
  10. start = time.time()for i inrange(10):
  11. session.post('http://httpbin.org/delay/2')print(f'Finished {i + 1} requests')
  12. end = time.time()print('Cost time for post', end - start)

运行结果

  1. Finished 1 requests
  2. Finished 2 requests
  3. Finished 3 requests
  4. Finished 4 requests
  5. Finished 5 requests
  6. Finished 6 requests
  7. Finished 7 requests
  8. Finished 8 requests
  9. Finished 9 requests
  10. Finished 10 requests
  11. Cost time for get 29.42441463470459
  12. Finished 1 requests
  13. Finished 2 requests
  14. Finished 3 requests
  15. Finished 4 requests
  16. Finished 5 requests
  17. Finished 6 requests
  18. Finished 7 requests
  19. Finished 8 requests
  20. Finished 9 requests
  21. Finished 10 requests
  22. Cost time for post 2.611323595046997
  23. Process finished with exit code 0

这时候就看到 GET 请求由于没有缓存,就花了 24 多秒才结束,而 POST 由于使用了缓存,2秒多就结束了。

2.3.3 Cache Headers 方法

除了我们自定义缓存,requests-cache 还支持解析 HTTP Request / Response Headers 并根据 Headers 的内容来缓存。

代码展示

  1. # -*- coding:utf-8 -*-# @Time : 2022-03-18# @Author : carl_DJimport time
  2. import requests
  3. import requests_cache
  4. requests_cache.install_cache('demo_headers_cache')
  5. start = time.time()
  6. session = requests.Session()for i inrange(10):#Request Headers 里面加上了 Cache-Control no-store
  7. session.get('http://httpbin.org',
  8. headers={'Cache-Control':'no-store'})print(f'Finished {i + 1} requests')
  9. end = time.time()print('Cost time for get', end - start)
  10. start = time.time()

在 Request Headers 里面加上了 Cache-Control 为 no-store,即使我们声明了缓存那也不会生效。

3、 总结

看到这里,今天的分享就差不多到这里了。
在实际应用中,如果循环爬取的话,requests_cache确实是一个好的方法,
即节省时间,有提高效率,
关键可以利用节省的时间,来泡泡澡。


本文转载自: https://blog.csdn.net/wuyoudeyuer/article/details/123571369
版权归原作者 Carl_奕然 所有, 如有侵权,请联系我们删除。

“Python3,此神器,让爬取速率提升10倍。”的评论:

还没有评论