2016-06-10 44 views
2

pyhton3脚本下载使用urlretrieve一些在互联网上的图像,我想用完成百分比下载速度添加进度为每下载。如何使用进度模块urlretrieve

progressbar模块似乎是一个很好的解决方案,不过虽然我已经通过their examples观看,范例4似乎是正确的事情,我仍然无法理解如何将它环绕的urlretrieve

我想我应该增加第三个参数:

urllib.request.urlretrieve('img_url', 'img_filename', some_progressbar_based_reporthook) 

但我怎么正确地定义它?

回答

2

钩被定义为:

urlretrieve(url[, filename[, reporthook[, data]]]) “的第三个参数,如果存在的话,是将上建立的网络连接的一次,之后读取每个块 后一度被称为 钩功能。 hook将传递三个参数;目前为止传输的块数为 ,块大小以字节为单位,并且文件的总大小为 第三个参数可能为-1,在旧的FTP服务器上不返回 文件大小以响应检索请求“。

所以,你可以写出如下钩:

# Global variables 
pbar = None 
downloaded = 0 

def show_progress(count, block_size, total_size): 
    if pbar is None: 
     pbar = ProgressBar(maxval=total_size) 

    downloaded += block_size 
    pbar.update(block_size) 
    if downloaded == total_size: 
     pbar.finish() 
     pbar = None 
     downloaded = 0 

作为一个方面说明,我强烈建议你使用请求库,它是一个更容易使用,你可以重复的进行iter_content()方法的响应。

+0

谢谢Doron。但我仍然不明白如何使用它。如果我做'urllib.request.urlretrieve('img_url','img_filename',reporthook = show_progress())',那么我得到'TypeError',告诉函数缺少所有3个必需的位置参数。 – Vasily

+0

再次感谢,我查了一下请求,它真的好多了。因此,如果我找到了你的话 - 我可以通过'r.headers(['Content-length'])''和'r.iter_content()'中的块添加当前进度来实现文件大小,对吧? – Vasily

+1

是的。 '用于r.iter_content()'中的块,在里面你可以执行'downloaded + = len(chunk)',然后用下载的值更新pbar。不要忘记用'stream = True'发送请求。查看请求文档。 –

1

其他答案中的建议没有超过1%的进展。这是一个完整的实现,适用于Python 3:

import progressbar 
import urllib.request 


pbar = None 


def show_progress(block_num, block_size, total_size): 
    global pbar 
    if pbar is None: 
     pbar = progressbar.ProgressBar(maxval=total_size) 

    downloaded = block_num * block_size 
    if downloaded < total_size: 
     pbar.update(downloaded) 
    else: 
     pbar.finish() 
     pbar = None 


urllib.request.urlretrieve(model_url, model_file, show_progress)