【问题标题】:Python 3: How to create a text progress bar for downloading files?Python 3:如何创建用于下载文件的文本进度条?
【发布时间】:2015-09-01 01:34:59
【问题描述】:

我目前有这个:

def download_dropbox(url, pre_file_name):
    file = url[42:]
    file = file[:-5]
    file_name = pre_file_name + file
    print('Downloading from ' + url + ' to ' + file_name)
    print(file)
    u = urllib.request.urlopen(url)
    data = u.read()
    u.close()

    with open(file_name, "wb") as f:
        f.write(data)
    print('Download Completed from ' + url + ' and saved to ' + file_name)

这基本上是从保管箱下载文件并将其保存到目录中。但是我希望能够拥有某种文本进度条,例如:


[====]50%


或


50%

我认为最困难的部分是使用任何外部模块,如加载栏模块等。另外,正如标题所述,我在 python 3 中需要它。谢谢。

编辑:

感谢 Martin Evans 读取 while 循环和进度条的数据,这是代码的最终结果:

#Get the total number of bytes of the file to download before downloading
print ("opening url:", url)
u = urllib.request.urlopen(url)
meta = u.info()
print(str(meta).split())
metaInfo = str(meta).split()
print(len(metaInfo))
print ("Content-Length:" + metaInfo[46] + " bytes")
fileTotalbytes=int(metaInfo[46])

data_blocks = []
# total = int(metaInfo[46])
total=0

while True:
    block = u.read(1024)
    data_blocks.append(block)
    total += len(block)
    hash = ((60*total)//fileTotalbytes)
    print("[{}{}] {}%".format('#' * hash, ' ' * (60-hash), int(total/fileTotalbytes*100)), end="\r")

    if not len(block):
        break

data=b''.join(data_blocks) #had to add b because I was joining bytes not strings
u.close()

with open('test.zip', "wb") as f:
        f.write(data)

【问题讨论】:

    标签: python download progress-bar


    【解决方案1】:

    要回答您的主要问题,如何制作文本进度条,您可以使用以下内容来给您一个想法:

    import time
    
    for n in range(1,101):
        hash = ((60*n)//100)
        print("[{}{}] {}%".format('#' * hash, ' ' * (60-hash), n), end="\r")
        time.sleep(0.05)
    

    这将为您提供以下信息:

    [###########################                                 ] 45%
    

    不过,您的主要问题是没有明显的方法来确定最终将下载多少字节,除非您事先已经知道要下载的项目的确切大小。如果您控制服务器端,那么您可以安排在开始之前获得长度。

    您可以首先将您的 read() 行转换为类似以下内容:

    u = urllib.request.urlopen(url)
    
    data_blocks = []
    total = 0
    
    while True:
        block = fd.read(1024)
        data_blocks.append(block)
        total += len(block)
        print("Downloaded {} bytes".format(total), end="\r")
    
        if not len(block):
            break
    
    data = "".join(data_blocks)
    u.close()
    

    通过这种方式,您一次阅读一点,然后可以提供反馈。

    【讨论】:

    • 谢谢,这就是我要找的。我不得不进行一些调整,例如将 fd.read(1024) 更改为 u.read(1024)。并且 join(data_blocks) 也用于连接字符串。对于字节,我必须使用 b''.join(data_blocks)。我还想出了一种在使用 urllib 模块中的 info() 下载文件之前获取文件字节的方法。我用你的添加制作了我的代码的最终版本,它完美地工作。再次感谢您的帮助。
    【解决方案2】:

    您可以在开头使用带有\r 的 print 以转到行首并覆盖前面的文本(因此,如果要清除字符,则需要写空格)。这是一个简单的例子:

    from time import sleep
    x = 0
    while x < 20:
        print('\r' + '.' * x, end="")
        x += 1
        sleep(0.1)
    

    【讨论】:

    • 感谢您的加载栏,但是您如何使用它来处理下载的实际进度。因为到目前为止,我的屏幕不动,告诉用户文件正在下载。我希望它自己显示下载进度。
    猜你喜欢
    • 1970-01-01
    • 2013-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多