Python 3: How to create a text progress bar for downloading files?

*爱你&永不变心* 提交于 2020-01-06 20:39:06

问题


I have currently this:

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)

This basically downloads files from dropbox and saves it to a directory. However I want to be able to have some sort of text progress bar like:


[==== ]50%


OR


50%

The hard part i would think is doing it with any external modules like the loading bar module, etc. Also, as the title states, I need it in python 3. Thank-you.

Edit:

Thanks to Martin Evans for the data read while loop and progress bar here is the end result of the code:

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

回答1:


To answer your main question, how to make a text progress bar, you could use something like the following to give you an idea:

import time

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

This would give you the following:

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

Your main problem though is that there is no obvious way to determine how many bytes will eventually be downloaded unless you already know the exact size of the item being downloaded beforehand. If you control the server end then you could arrange for the length to be obtained before starting.

You can though start by at least converting your read() line to something like the following:

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

By doing it this way, you read it a bit at a time and can then provide feedback.




回答2:


You can use print with \r at the start to go to the start of the line and write over the previous text (so you need to write spaces if you want to clear a character). Here's a simple example:

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


来源:https://stackoverflow.com/questions/32288113/python-3-how-to-create-a-text-progress-bar-for-downloading-files

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!