2012-04-24 204 views
2

我有多个URL返回zip文件。大多数的文件,我可以在使用的urllib2库如下下载:使用python下载大zip文件

request = urllib2.urlopen(url) 
zip_file = request.read() 

我遇到的问题是,其中一个文件是35MB的大小(压缩),我从来没有能够使用这个库完成下载。我可以通过wget和浏览器正常下载它。

我已经尝试下载在chuncks文件是这样的:

request = urllib2.urlopen(url) 
buffers = [] 
while True: 
    buffer = request.read(8192) 
    if buffer: 
     buffers.append(buffer) 
    else: 
     break 
final_file = ''.join(buffers) 

但这还没有完成下载。没有错误发生,所以很难调试正在发生的事情。不幸的是,我无法在这里发布url /文件的例子。

任何建议/意见?

+0

如果没有更多信息或重现它的URL,很难进行调试。但是,为什么不使用'final_file = request.read()'?你上面的代码构建了一个将所有数据存储在内存中的字符串数组,所以我没有看到任何使代码复杂化的原因。 – 2012-04-24 20:19:27

+0

可能重复[如何使用urllib2在python中下载zip文件?](http://stackoverflow.com/questions/4028697/how-do-i-download-a-zip-file-in-python-using -urllib2) – 2012-04-24 20:21:17

+0

@benhoyt这是我第一次尝试,但它没有奏效。这就是为什么我试图分割文件的大块 – duduklein 2012-04-24 20:29:12

回答

2

这是从我的应用程序复制/粘贴下载它自己的更新安装程序。它以块的形式读取文件并立即将块保存在磁盘上的输出文件中。

def DownloadThreadFunc(self): 
    try: 
     url = self.lines[1] 
     data = None 
     req = urllib2.Request(url, data, {}) 
     handle = urllib2.urlopen(req) 

     self.size = int(handle.info()["Content-Length"]) 
     self.actualSize = 0 
     name = path.join(DIR_UPDATES, url.split("/")[-1]) 
     blocksize = 64*1024 

     fo = open(name, "wb") 
     while not self.terminate: 
      block = handle.read(blocksize) 
      self.actualSize += len(block) 
      if len(block) == 0: 
       break 
      fo.write(block) 
     fo.close() 
    except (urllib2.URLError, socket.timeout), e: 
     try: 
      fo.close() 
     except: 
      pass 
     error("Download failed.", unicode(e)) 

我用self.sizeself.actualSize显示在GUI线程和self.terminate下载进度,如果需要从GUI按钮取消下载。

+0

这完美的工作!非常感谢。但是,你能告诉我为什么我的简化版本不起作用吗? – duduklein 2012-04-24 21:48:23

+0

不知道。但我怀疑这种结构:'如果缓冲区:'。我喜欢直接将块存储到磁盘,以便可以在输出文件上看到进度。 – Fenikso 2012-04-25 07:51:47

+0

我明白你的观点。我试过你的代码版本,也只是在内存中存储文件,它也可以。它可能是我的初始缓冲区大小(太小)? – duduklein 2012-04-25 11:16:28