2008-09-09 54 views
47

我正在編寫一個小應用程序來通過http下載文件(例如,描述爲here)。如何在Python中編寫下載進度指示器?

我還想包括一個下載進度指示器,顯示下載進度的百分比。

這裏是我想出了:

 
    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%

任何其他的想法或建議這樣做呢?

有點煩人的一件事是百分比的第一個數字在終端閃爍的光標。有沒有辦法來防止這種情況?有沒有辦法隱藏光標?

編輯:

這裏使用全局變量在dlProgress文件名和 '\ r' 的代碼更好的選擇:

 
    global rem_file # global variable to be used in dlProgress 

    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%

然後光標出現在行的結尾處。好多了。

+0

'全球rem_file`有道理只有在你將它綁定到一個新對象`rem_file = ...`的函數內,否則(如果你只是讀取它的值)`global rem_file`是沒有必要的。 – jfs 2008-12-14 13:04:51

+0

你也可以在標準輸出上做一個/ r + flush()。我只是猜測這是基於您提到的終端行爲在Windows中運行。 – meawoppl 2014-05-02 20:53:54

+0

相關http://stackoverflow.com/questions/15644964/python-progress-bar-and-downloads – 2015-03-22 06:35:18

回答

17

有在http://pypi.python.org/pypi/progressbar/2.2文本進度條庫的Python,你可能會發現有用:

This library provides a text mode progressbar. This is tipically used to display the progress of a long running operation, providing a visual clue that processing is underway.

The ProgressBar class manages the progress, and the format of the line is given by a number of widgets. A widget is an object that may display diferently depending on the state of the progress. There are three types of widget: - a string, which always shows itself; - a ProgressBarWidget, which may return a diferent value every time it's update method is called; and - a ProgressBarWidgetHFill, which is like ProgressBarWidget, except it expands to fill the remaining width of the line.

The progressbar module is very easy to use, yet very powerful. And automatically supports features like auto-resizing when available.

4

如果使用curses軟件包,則可以更好地控制該控制檯。它的代碼複雜性成本也更高,除非你正在開發一個大型的基於控制檯的應用程序,否則可能是不必要的。

對於一個簡單的解決方案,你可以隨時把紡車在狀態的messge(字符|, \, -, /這實際上看起來閃爍的光標在尼斯序列結束

13

您也可以嘗試:

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

在字符串的開始處使用單個回車符而不是幾個退格符,您的光標仍然會閃爍,但會在百分號後閃爍,而不是在第一個數字之後閃爍,並且只有一個控制字符而不是三個可能會少閃爍。

0

對於您可能需要以避免瘋狂的百分比,以有這個線小檔案:

sys.stdout的.write(「\ r%2d %%」%percent)

sys.stdout。沖洗()

乾杯

1

我用這個代碼:

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() 
0

遲到了,像往常一樣。下面是支持報告進展情況的實現,如核心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) 
6

對於它的價值,這是我用得到它的工作代碼:

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)) 
1
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)