我正在开发一个下载多个页面的程序,我使用grequests来最小化下载时间,并且因为它支持请求会话,因为程序需要登录。 grequests基于gevent,这使我在编译程序时遇到困难(py2exe,bbfreeze)。有没有可以使用请求会话的替代方案?或者有任何关于使用gevent编译程序的提示吗?
我不能使用pyinstaller :我必须使用允许更新的esky。
答案 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+中,它的工作方式应该如此。