如何在Python中编写下载进度指示器?

我正在写一个小应用程序通过http下载文件(例如, 在这里描述)。

我还想包括一个下载进度指示器,显示下载进度的百分比。

这是我想出来的:

     sys.stdout.write(rem_file +“...”)    
     urllib.urlretrieve(rem_file,loc_file,reporthook = dlProgress)

     def dlProgress(count,blockSize,totalSize):
       percent = int(count * blockSize * 100 / totalSize)
       sys.stdout.write(“%2d %%”%percent)
       sys.stdout.write函数( “\ b \ B \ B”)
       sys.stdout.flush()

输出:MyFileName … 9%

任何其他想法或build议要做到这一点?

有一点令人讨厌的是百分比第一位的terminal闪烁的光标。 有没有办法来防止这一点? 有没有办法隐藏光标?

编辑:

这里有一个更好的替代方法,在dlProgress和'\ r'代码中使用全局variables作为文件名:

    全局rem_file#在dlProgress中使用的全局variables

     urllib.urlretrieve(rem_file,loc_file,reporthook = dlProgress)

     def dlProgress(count,blockSize,totalSize):
       percent = int(count * blockSize * 100 / totalSize)
       sys.stdout.write(“\ r”+ rem_file +“...%d %%”%percent)
       sys.stdout.flush()

输出:MyFileName … 9%

光标出现在行的结尾处。 好多了。

http://pypi.python.org/pypi/progressbar/2.2有一个python的文本进度条库,你可能会觉得很有用:;

这个库提供了一个文本模式的进度条。 这通常用于显示长时间运行的进度,提供处理正在进行的视觉线索。

ProgressBar类pipe理进度,线的格式由一些小部件给出。 小部件是根据进度状态可能显示不同的对象。 有三种types的小部件: – 一个string,总是显示自己; – 一个ProgressBarWidget,它每次调用update方法都会返回一个不同的值; 以及ProgressBarWidgetHFill,它像ProgressBarWidget一样,只是展开以填充行的剩余宽度。

进度条模块非常易于使用,但非常强大。 并自动支持function,如可用时自动resize。

你也可以尝试:

 sys.stdout.write("\r%2d%%" % percent) sys.stdout.flush() 

使用一个回车在string的开头而不是几个退格。 您的光标仍然会闪烁,但会在百分号后闪烁,而不是在第一个数字之后闪烁,并且只有一个控制字符,而不是三个闪烁。

如果使用curses包,则对控制台的控制更加强大。 它的代码复杂性也更高,除非你正在开发一个大型的基于控制台的应用程序,否则可能是不必要的。

对于一个简单的解决scheme,你总是可以把旋转轮置于状态边界(字符序列|, \, -, /在闪烁的光标下实际上看起来不错。

对于它的价值,这里是我用来使它工作的代码:

 from urllib import urlretrieve from progressbar import ProgressBar, Percentage, Bar url = "http://......." fileName = "file" pbar = ProgressBar(widgets=[Percentage(), Bar()]) urlretrieve(url, fileName, reporthook=dlProgress) def dlProgress(count, blockSize, totalSize): pbar.update( int(count * blockSize * 100 / totalSize) ) 

我用这个代码:

 url = (<file location>) file_name = url.split('/')[-1] u = urllib2.urlopen(url) f = open(file_name, 'wb') meta = u.info() file_size = int(meta.getheaders("Content-Length")[0]) print "Downloading: %s Bytes: %s" % (file_name, file_size) file_size_dl = 0 block_sz = 8192 while True: buffer = u.read(block_sz) if not buffer: break file_size_dl += len(buffer) f.write(buffer) status = r"%10d [%3.2f%%]" % (file_size_dl, file_size_dl * 100. / file_size) status = status + chr(8)*(len(status)+1) print status, f.close() 

对于小文件,你可能需要有这样的线路,以避免疯狂的百分比:

sys.stdout.write(“\ r%2d %%”%percent)

sys.stdout.flush()

干杯

多数民众赞成我如何做到这一点可以帮助你: https : //github.com/mouuff/MouDownloader/blob/master/api/download.py

晚会,像往常一样。 这里有一个支持报告进度的实现,比如核心urlretrieve

 import urllib2 def urlretrieve(urllib2_request, filepath, reporthook=None, chunk_size=4096): req = urllib2.urlopen(urllib2_request) if reporthook: # ensure progress method is callable if hasattr(reporthook, '__call__'): reporthook = None try: # get response length total_size = req.info().getheaders('Content-Length')[0] except KeyError: reporthook = None data = '' num_blocks = 0 with open(filepath, 'w') as f: while True: data = req.read(chunk_size) num_blocks += 1 if reporthook: # report progress reporthook(num_blocks, chunk_size, total_size) if not data: break f.write(data) # return downloaded length return len(data) 
 def download_progress_hook(count, blockSize, totalSize): """A hook to report the progress of a download. This is mostly intended for users with slow internet connections. Reports every 5% change in download progress. """ global last_percent_reported percent = int(count * blockSize * 100 / totalSize) if last_percent_reported != percent: if percent % 5 == 0: sys.stdout.write("%s%%" % percent) sys.stdout.flush() else: sys.stdout.write(".") sys.stdout.flush() last_percent_reported = percent urlretrieve(url, filename, reporthook=download_progress_hook)