对于初学者我是python的新手,所以下面的代码可能不是最干净的。对于一个程序,我需要下载大约500个网页。 url存储在一个由前一个函数填充的数组中。下载部分是这样的:
def downloadpages(num):
import urllib
for i in range(0,numPlanets):
urllib.urlretrieve(downloadlist[i], 'webpages/'+names[i]'.htm')
每个文件只有大约20KB,但下载所有文件至少需要10分钟。下载总组合大小的单个文件应该只需要一两分钟。有没有办法加快速度呢?感谢
修改:对于有兴趣的人,按照http://code.google.com/p/workerpool/wiki/MassDownloader上的示例并使用50个主题,下载时间从最初的10分钟加上减少到大约20秒。随着线程增加直到大约60个线程,下载速度继续下降,之后下载时间再次开始上升。
答案 0 :(得分:4)
但是你不是在这里下载单个文件。您正在下载500个单独的页面,每个连接都涉及开销(用于初始连接),以及服务器正在执行的任何其他操作(是否为其他人服务?)。
无论哪种方式,下载500 x 20kb与下载该大小的单个文件不同。
答案 1 :(得分:3)
使用线程可以显着加快执行速度(但要小心,不要使服务器过载)。
介绍材料/代码示例:
答案 2 :(得分:2)
您可以使用greenlet来执行此操作。
E.G with eventlet lib:
urls = [url1, url2, ...]
import eventlet
from eventlet.green import urllib2
def fetch(url):
return urllib2.urlopen(url).read()
pool = eventlet.GreenPool()
for body in pool.imap(fetch, urls):
print "got body", len(body)
池中的所有调用都是伪模拟的。
当然,您必须先安装带有pip或easy_install的eventlet。
您在Python中有几个greenlet实现。您可以使用gevent或其他方法执行相同的操作。
答案 3 :(得分:0)
除了使用某种并发性之外,还要确保使用的任何方法来使请求使用HTTP 1.1连接持久性。这将允许每个线程只打开一个连接并请求所有页面,而不是为每个请求设置TCP / IP设置/拆卸。不确定urllib2默认是否这样做;你可能不得不自己动手。