可以让grequests和requests_cache一起工作吗?

4 投票
1 回答
1275 浏览
提问于 2025-04-17 22:18

看看这段代码:

import requests
import grequests
import requests_cache
requests_cache.install_cache('bla')

urls = [
    'http://www.heroku.com',
    'http://python-tablib.org',
    'http://httpbin.org',
    'http://python-requests.org',
    'http://kennethreitz.com'
]

rs = (grequests.get(u) for u in urls)
results = grequests.map(rs)

我本以为执行完这段代码后,会在当前目录下找到一个叫 bla.sqlite 的文件,并且执行

results = grequests.map(rs)

会快很多,因为数据会从sqlite的缓存中获取。可惜事实并非如此,文件根本没有被创建,而且速度也没有提升。当我用requests代替grequests时,一切都正常。所以问题就如标题所说:grequests和requests_cache能一起工作吗? 如果可以的话,怎么做呢?

1 个回答

6

requests_cache.install_cache()这个函数会对requests.Session进行修改,但你已经导入了grequests,它使用的是:

from requests import Session

因此,grequests并不会使用被修改过的会话对象。

你可以把导入的代码移到安装缓存之后再执行:

import requests_cache
requests_cache.install_cache('bla')
import grequests

另外,你也可以创建一个CachedSession对象,然后把这个对象作为session参数传给grequests.get()(以及相关的方法):

import grequests
import requests_cache

session = requests_cache.CachedSession('bla')

urls = [
    'http://www.heroku.com',
    'http://python-tablib.org',
    'http://httpbin.org',
    'http://python-requests.org',
    'http://kennethreitz.com'
]

rs = (grequests.get(u, session=session) for u in urls)
results = grequests.map(rs)

需要注意的是,缓存存储的后端可能无法安全地处理并发访问。例如,sqlite后端使用了线程锁,这可能会导致冲突。

撰写回答