【发布时间】:2016-06-11 05:21:34
【问题描述】:
我正在编写一个脚本来从网站下载视频。我添加了一个报告挂钩来获取下载进度。因此,到目前为止,它显示了下载数据的百分比和大小。我认为添加下载速度和 eta 会很有趣。
问题是,如果我使用简单的speed = chunk_size/time,显示的速度足够准确,但会像疯了一样跳来跳去。因此,我使用了下载单个块所用时间的历史记录。类似speed = chunk_size*n/sum(n_time_history).
现在它显示出稳定的下载速度,但它肯定是错误的,因为它的值以几比特/秒为单位,而下载的文件明显以更快的速度增长。
有人可以告诉我哪里出错了吗?
这是我的代码。
def dlProgress(count, blockSize, totalSize):
global init_count
global time_history
try:
time_history.append(time.monotonic())
except NameError:
time_history = [time.monotonic()]
try:
init_count
except NameError:
init_count = count
percent = count*blockSize*100/totalSize
dl, dlu = unitsize(count*blockSize) #returns size in kB, MB, GB, etc.
tdl, tdlu = unitsize(totalSize)
count -= init_count #because continuation of partial downloads is supported
if count > 0:
n = 5 #length of time history to consider
_count = n if count > n else count
time_history = time_history[-_count:]
time_diff = [i-j for i,j in zip(time_history[1:],time_history[:-1])]
speed = blockSize*_count / sum(time_diff)
else: speed = 0
n = int(percent//4)
try:
eta = format_time((totalSize-blockSize*(count+1))//speed)
except:
eta = '>1 day'
speed, speedu = unitsize(speed, True) #returns speed in B/s, kB/s, MB/s, etc.
sys.stdout.write("\r" + percent + "% |" + "#"*n + " "*(25-n) + "| " + dl + dlu + "/" + tdl + tdlu + speed + speedu + eta)
sys.stdout.flush()
编辑:
更正了逻辑。现在显示的下载速度要好得多。
随着我增加用于计算速度的历史记录长度,稳定性会增加,但不会显示速度的突然变化(如果下载停止等)。
我如何使它稳定,但对大的变化敏感?
我意识到这个问题现在更面向数学,但如果有人能帮助我或为我指明正确的方向,那就太好了。
另外,请告诉我是否有更有效的方法来完成此操作。
【问题讨论】:
-
p=30和speed = chunk_size*n/sum(n_time_history) if n<p else chunk_size*p/sum(n_time_history[-p:])怎么样,否则你希望p成为 -
@TomaszPlaskota 这和我在代码中所做的不一样吗?
-
我的错,只是在看你描述的逻辑。由于您已经这样做了,因此可以通过对时间范围进行分组(即 0-30、30-60、60-90 或您喜欢的 w/e 间隔),然后从该集合中去除最低/最高平均值,并计算得出更好的估计值大约没有那些极端的时间。或者使用任何其他统计过滤方法代替最小值/最大值。编辑:为了使其对最近的变化敏感,引入了一些随着时间推移而减少的权重。
-
谢谢。没有考虑过重。至于你建议的其他内容,我的数学太糟糕了,无法理解,但我会照样研究它们。
标签: python performance python-3.x download urllib