首页 > 编程语言 >Python3,此神器,让爬取速率提升10倍。

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

时间:2022-12-13 10:04:30浏览次数:68  
标签:10 cache 神器 print session time requestsFinished requests Python3


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

  • ​​1、引言​​
  • ​​2、requests_cache​​
  • ​​2.1 介绍​​
  • ​​2.2 安装​​
  • ​​2.3 代码实例​​
  • ​​2.3.1 CachedSession 方法​​
  • ​​2.3.2 install_cache方法​​
  • ​​2.3.3 Cache Headers 方法​​
  • ​​3、 总结​​

1、引言

小屌丝:有没有能提升 爬取速率的方法,

小鱼:嗯,提升方法有好多种,例如 多线程、装饰器,都可以啊

小屌丝:嗯,那有没有其他的方法呢?

小鱼:额,容我想一下,

Python3,此神器,让爬取速率提升10倍。_开发语言


小鱼:嘿~ 想到了

小屌丝:那是啥?

小鱼:requests_cache

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

此时,小屌丝的表情

2、requests_cache

2.1 介绍

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

2.2 安装

老规矩, pip 方式安装:

pip install requests-cache

其他方式安装:

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

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

2.3 代码实例

2.3.1 CachedSession 方法

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

代码展示

# -*- coding:utf-8 -*-
# @Time : 2022-03-18
# @Author : carl_DJ

'''
requests 方法请求
'''
import requests
import time

#开始时间
start = time.time()
#session
session = requests.session()

#循环爬取,10次
for i in range(10):
session.get('http://httpbin.org/delay/2')
print(f'Finish{i + 1} requests')

end = time.time()
print('Cost time', end - start)

运行结果

Finish2 requests
Finish3 requests
Finish4 requests
Finish5 requests
Finish6 requests
Finish7 requests
Finish8 requests
Finish9 requests
Finish10 requests
Cost time 24.35784935951233

Process finished with exit code 0

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

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

代码展示

# -*- coding:utf-8 -*-
# @Time : 2022-03-18
# @Author : carl_DJ

import requests_cache
import time

start = time.time()
#CachedSession方法,在本地生成 demo_cache.sqlite
session = requests_cache.CachedSession('demo_cache')

for i in range(10):
session.get('http://httpbin.org/delay/2')
print(f'Finish{i + 1} requests')

end = time.time()
print('Cost time', end -start)

运行结果

Finish1 requests
Finish2 requests
Finish3 requests
Finish4 requests
Finish5 requests
Finish6 requests
Finish7 requests
Finish8 requests
Finish9 requests
Finish10 requests
Cost time 8.624990701675415

Process finished with exit code 0

本地生成demo_cache.sqlite数据库

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


文件的内容,我们看下

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


我们可以可以看到,这个 key-value 记录中的 key 是一个 hash 值,value 是一个 Blob 对象,里面的内容就是 Response 的结果。

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

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

2.3.2 install_cache方法

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

代码展示

# -*- coding:utf-8 -*-
# @Time : 2022-03-18
# @Author : carl_DJ

import requests
import requests_cache
import time

#调用requests_cache.install_cache方法
requests_cache.install_cache('demo_path_cache')

start = time.time()
session = requests.session()
for i in range(10):
session.get('http://httpbin.org/delay/2')
print(f'Finish{i + 1} requests')

end = time.time()
print('Cost time', end -start)

运行结果

Finish1 requests
Finish2 requests
Finish3 requests
Finish4 requests
Finish5 requests
Finish6 requests
Finish7 requests
Finish8 requests
Finish9 requests
Finish10 requests
Cost time 7.516860723495483

Process finished with exit code 0

生成文件

Python3,此神器,让爬取速率提升10倍。_缓存_05

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

代码展示

# -*- coding:utf-8 -*-
# @Time : 2022-03-18
# @Author : carl_DJ

import requests
import requests_cache
import time

#使用filesystem作为缓存对象
requests_cache.install_cache('demo_file_cache', backend='filesystem')

start = time.time()
session = requests.session()
for i in range(10):
session.get('http://httpbin.org/delay/2')
print(f'Finish{i + 1} requests')

end = time.time()
print('Cost time', end -start)

运行结果

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


Python3,此神器,让爬取速率提升10倍。_开发语言_07


其他后端有:

[‘dynamodb’, ‘filesystem’, ‘gridfs’, ‘memory’, ‘mongodb’, ‘redis’, ‘sqlite’]

具体的差异,我们来看下

Backend

Class

Alias

Dependencies

SQLite

SQLiteCache

sqlite

Redis

RedisCache

redis

redis-py

MongoDB

MongoCache

mongodb

pymongo

GridFS

GridFSCache

gridfs

pymongo

DynamoDB

DynamoDbCache

dynamodb

boto3

Filesystem

FileCache

filesystem

Memory

BaseCache

memory

如果使用redis

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

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

# -*- coding:utf-8 -*-
# @Time : 2022-03-18
# @Author : carl_DJ

import time
import requests
import requests_cache

#allowable_methods 方式,只对post请求进行缓存
requests_cache.install_cache('demo_post_cache', allowable_methods=['POST'])

start = time.time()
session = requests.Session()
for i in range(10):
session.get('http://httpbin.org/delay/2')
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/2')
print(f'Finished {i + 1} requests')
end = time.time()
print('Cost time for post', end - start)

运行结果

Finished 1 requests
Finished 2 requests
Finished 3 requests
Finished 4 requests
Finished 5 requests
Finished 6 requests
Finished 7 requests
Finished 8 requests
Finished 9 requests
Finished 10 requests
Cost time for get 29.42441463470459
Finished 1 requests
Finished 2 requests
Finished 3 requests
Finished 4 requests
Finished 5 requests
Finished 6 requests
Finished 7 requests
Finished 8 requests
Finished 9 requests
Finished 10 requests
Cost time for post 2.611323595046997

Process finished with exit code 0

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

2.3.3 Cache Headers 方法

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

代码展示

# -*- coding:utf-8 -*-
# @Time : 2022-03-18
# @Author : carl_DJ

import time
import requests
import requests_cache

requests_cache.install_cache('demo_headers_cache')

start = time.time()
session = requests.Session()
for i in range(10):
#Request Headers 里面加上了 Cache-Control 为 no-store
session.get('http://httpbin.org',
headers={
'Cache-Control': 'no-store'
})
print(f'Finished {i + 1} requests')

end = time.time()
print('Cost time for get', end - start)
start = time.time()

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

3、 总结

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


标签:10,cache,神器,print,session,time,requestsFinished,requests,Python3
From: https://blog.51cto.com/u_15910936/5932510

相关文章