我正在编写一个小应用程序来通过http下载文件(例如,描述为here)。
我还想包含一个显示下载进度百分比的小下载进度指示器。
以下是我提出的建议:
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%
光标显示在行的END处。好多了。
答案 0 :(得分:17)
在http://pypi.python.org/pypi/progressbar/2.2有一个python的文本进度条库,您可能会发现它很有用:
此库提供文本模式进度条。这通常用于显示长时间运行的进度,提供处理正在进行的视觉线索。
ProgressBar类管理进度,行的格式由许多小部件给出。窗口小部件是可以根据进度状态不同地显示的对象。小部件有三种类型: - 一个字符串,总是显示自己; - ProgressBarWidget,每次调用update方法时都可能返回不同的值;和 - 一个ProgressBarWidgetHFill,它类似于ProgressBarWidget,但它会扩展以填充该行的剩余宽度。
进度条模块非常易于使用,但功能非常强大。并自动支持自动调整大小等功能。
答案 1 :(得分:15)
您也可以尝试:
sys.stdout.write("\r%2d%%" % percent)
sys.stdout.flush()
在字符串的开头使用单个回车符而不是几个退格键。你的光标仍然会闪烁,但它会在百分号后闪烁,而不是在第一个数字下面闪烁,并且使用一个控制字符而不是三个控制字符可能会减少闪烁。
答案 2 :(得分: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) )
答案 3 :(得分:4)
如果使用curses
包,则可以更好地控制控制台。它还会带来更高的代码复杂性,除非您正在开发一个基于控制台的大型应用程序,否则可能是不必要的。
对于一个简单的解决方案,您始终可以将旋转轮置于状态消息的末尾(字符序列|, \, -, /
,它在闪烁的光标下实际上看起来很好。
答案 4 :(得分: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()
答案 5 :(得分: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)
答案 6 :(得分:0)
对于小文件,您可能需要使用此行以避免疯狂的百分比:
sys.stdout.write(“\ r \ n%2d %%”%%)
sys.stdout.flush()
干杯
答案 7 :(得分:0)
多数民众赞成我这样做可以帮助你: https://github.com/mouuff/MouDownloader/blob/master/api/download.py
答案 8 :(得分: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)