greuests alt - python

时间:2014-01-16 23:17:39

标签: python concurrency compilation

我正在开发一个下载多个页面的程序,我使用grequests来最小化下载时间,并且因为它支持请求会话,因为程序需要登录。 grequests基于gevent,这使我在编译程序时遇到困难(py2exe,bbfreeze)。有没有可以使用请求会话的替代方案?或者有任何关于使用gevent编译程序的提示吗?

我不能使用pyinstaller :我必须使用允许更新的esky。

1 个答案:

答案 0 :(得分:3)

当然,有很多选择。绝对没有理由你必须使用gevent - 或者greenlet来下载多个页面。

如果您正在尝试处理数千个连接,这是一回事,但通常并行下载只需要4-16个并发连接,而​​任何现代操作系统都可以运行4-16个线程。这是使用Python 3.2+的示例。如果您使用的是2.x或3.1,请从PyPI下载futures backport - 它是纯Python,因此您可以毫无困难地构建和打包它。

import concurrent.futures
import requests

def get_url(url, other, args):
    # your existing requests-based code here

urls = [your, list, of, page, urls, here]

with concurrent.futures.ThreadPoolExecutor() as pool:
    pool.map(get_url, urls)

如果您在主线程上的每次下载后都要进行一些简单的后处理,那么文档中的example会显示如何做到这一点。

如果您听说“由于GIL而导致Python中的线程不好”,那么您听错了。由于GIL,在Python 中执行CPU绑定工作的线程很糟糕。执行I / O绑定工作的线程(如下载网页)非常好。而与使用greenlets时的限制完全相同,就像您现有的grequests代码一样。


正如我所说,这不是唯一的选择。例如,与curl相比,requests(与其各种Python绑定中的任何一个)一开始就很难实现 - 但是一旦你这样做,让它为你复用多个下载是没有的比一次做一件事要困难得多。但是线程是最简单的替代方案,特别是如果你已经围绕greenlets编写代码。


*在2.x和3.1中,当后台线程正在执行I / O时,可能成为单个线程执行大量CPU工作的问题。在3.2+中,它的工作方式应该如此。