57

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

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

这是我想出的:

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

    def dlProgress(计数,块大小,总大小):
      百分比 = int(count*blockSize*100/totalSize)
      sys.stdout.write("%2d%%" % percent)
      sys.stdout.write("\b\b\b")
      sys.stdout.flush()

输出:我的文件名... 9%

还有其他想法或建议吗?

有点烦人的是终端中百分比的第一位数字上的闪烁光标。有没有办法防止这种情况?有没有办法隐藏光标?

编辑:

在 dlProgress 和 '\r' 代码中使用全局变量作为文件名的更好选择:

    global rem_file # 在 dlProgress 中使用的全局变量

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

    def dlProgress(计数,块大小,总大小):
      百分比 = int(count*blockSize*100/totalSize)
      sys.stdout.write("\r" + rem_file + "...%d%%" % percent)
      sys.stdout.flush()

输出:我的文件名...9%

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

4

10 回答 10

18

在http://pypi.python.org/pypi/progressbar/2.2有一个 Python 的文本进度条库 ,您可能会发现它很有用:

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

ProgressBar 类管理进度,行的格式由许多小部件给出。小部件是一个对象,可能会根据进度状态以不同方式显示。有三种类型的小部件: - 一个字符串,它总是显示自己;- 一个 ProgressBarWidget,每次调用 update 方法时可能返回不同的值;- 一个 ProgressBarWidgetHFill,它类似于 ProgressBarWidget,不同之处在于它会扩展以填充行的剩余宽度。

进度条模块非常易于使用,但功能非常强大。并自动支持可用时自动调整大小等功能。

于 2008-09-09T04:48:28.203 回答
15

你也可以试试:

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

在字符串的开头使用单个回车而不是多个退格。您的光标仍会闪烁,但它会在百分号之后而不是第一个数字下方闪烁,并且使用一个控制字符而不是三个控制字符可能会减少闪烁。

于 2008-09-09T04:21:09.157 回答
7

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

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) )
于 2016-03-15T21:52:32.137 回答
4

如果您使用该curses 软件包,您可以更好地控制控制台。它还以更高的代码复杂性为代价,除非您正在开发基于控制台的大型应用程序,否则它可能是不必要的。

对于一个简单的解决方案,您始终可以将旋转轮放在状态消息的末尾(|, \, -, /在闪烁的光标下实际上看起来不错的字符序列。

于 2008-09-09T04:14:37.393 回答
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()
于 2013-01-02T14:01:43.940 回答
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)
于 2017-04-18T14:43:56.927 回答
0

对于小文件,您可能需要这些行以避免疯狂的百分比:

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

sys.stdout.flush()

干杯

于 2009-04-01T10:04:19.397 回答
0

这就是我这样做可以帮助你: https ://github.com/mouuff/MouDownloader/blob/master/api/download.py

于 2012-10-14T08:31:23.217 回答
0

像往常一样,晚会迟到了。这是一个支持报告进度的实现,例如 core 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)
于 2015-02-10T04:38:33.730 回答
0

为避免像 106% 或类似的进度值,请遵循以下逻辑

percent = min(int(count * blockSize * 100 / totalSize), 100)
于 2022-01-18T05:23:42.140 回答