python中concurrent.futures的async和requests-futures的async有什么区别?

1 投票
1 回答
2093 浏览
提问于 2025-04-18 14:50

我用requests-futures这个库来异步抓取网页,也就是说可以同时去获取多个网页的内容。我的电脑有多个核心,所以我想要同时抓取很多网站。于是我尝试使用concurrent.futures这个库,发现它似乎也提供了异步的方法。那么,concurrent.futures的异步和requests-futures的异步有什么区别呢?如果它们是一样的,那我是不是可以不再使用requests-futures了?

1 个回答

5

requests-futures 其实就是在 concurrent.futures 这个库上面加了一个很小的包装。你可以通过查看这个 源代码 来了解这一点(为了简洁起见,文档字符串被省略了):

from concurrent.futures import ThreadPoolExecutor
from requests import Session
from requests.adapters import DEFAULT_POOLSIZE, HTTPAdapter

class FuturesSession(Session):

    def __init__(self, executor=None, max_workers=2, *args, **kwargs):
        super(FuturesSession, self).__init__(*args, **kwargs)
        if executor is None:
            executor = ThreadPoolExecutor(max_workers=max_workers)
            # set connection pool size equal to max_workers if needed
            if max_workers > DEFAULT_POOLSIZE:
                adapter_kwargs = dict(pool_connections=max_workers,
                                      pool_maxsize=max_workers)
                self.mount('https://', HTTPAdapter(**adapter_kwargs))
                self.mount('http://', HTTPAdapter(**adapter_kwargs))

        self.executor = executor

    def request(self, *args, **kwargs):
        func = sup = super(FuturesSession, self).request

        background_callback = kwargs.pop('background_callback', None)
        if background_callback:
            def wrap(*args_, **kwargs_):
                resp = sup(*args_, **kwargs_)
                background_callback(self, resp)
                return resp

            func = wrap

        return self.executor.submit(func, *args, **kwargs) # This returns a concurrent.futures.Future

当你使用 requests-futures 的时候,实际上是在使用 concurrent.futures.ThreadPoolExecutor。当你把一个任务提交给它时,它会返回一个 concurrent.futures.Future 对象。如果你觉得使用 requests-futures 提供的接口来处理 HTTP 请求更方便,那就继续用它吧,甚至可以把它返回的对象和 concurrent.futures 模块提供的其他方法一起使用。

撰写回答