demo 01:
#!/usr/bin/python #encoding:utf-8 import urllib import os def Schedule(a,b,c): ''' a:已经下载的数据块 b:数据块的大小 c:远程文件的大小 ''' per = 100.0*a*b/c if per > 100: per = 100 print '%.2f%%' % per url = 'http://download.dinpay.com/member/DinpayPusreV2.1.15_08.apk' #local = url.split('/')[-1] local = os.path.join('f://APK/','DinpayPusreV2.1.15_08-1.apk') urllib.urlretrieve(url,local,Schedule)
demo02:
我们对进度条的需求:一是进度信息在一行中显示;二是每次都能够动态擦除一行中上一次的内容。那么很自然的想到print有没有相应的转义符,还真有这么一个,” ”。
import time N = 1000 for i in range(N): print("进度:{0}%".format(round((i + 1) * 100 / N)), end=" ") time.sleep(0.01)
demo03:
环境:
- Python 3.6
- requests模块
- 对应文件的下载链接
讲解:
调用requests库函数时,默认verify=True,这会导致一个问题,当你的浏览器和网站SSL不匹配时,会报错。那解决办法也非常简单,就是把verify=False 这一句换成上一句。
既然要实现下载进度,那就要知道你要下载文件的总大小,还有你已经下载到的文件大小,那这些信心从哪得到呢?一般网页的Content-Length 就包含下载文件总大小,然后temp_size += len(chunk) 就是得到每次本地已经下载的文件大小,这样就能实现下载进度了(百分比)。
花哨的部分讲解,上面代码中调用标准输出刷新命令行,看到 回车符了吧,相当于每次循环就回车到命令行首,把每一行重新刷新一遍,所以看起来是动态的下载。
有些人下载文件很大怎么办,内存都装不下怎么办?那就要指定chunk_size = 1024,具体大小可以自己设置, 意思是下载一点chunk 就写一点到磁盘。又有人问了,那我下载下载就断了,前面那些不是白下了。。。其实这个问题可以用断点续传解决,但是前提是,该网站的文件支持断点续传,查看demo04代码
代码:
import sys import requests import os # 屏蔽warning信息,因为下面verify=False会报警告信息 requests.packages.urllib3.disable_warnings() def download(url, file_path): # verify=False 这一句是为了有的网站证书问题,为True会报错 r = requests.get(url, stream=True, verify=False) # 既然要实现下载进度,那就要知道你文件大小啊,下面这句就是得到总大小 total_size = int(r.headers['Content-Length']) temp_size = 0 with open(file_path, "w") as f: # iter_content()函数就是得到文件的内容, # 有些人下载文件很大怎么办,内存都装不下怎么办? # 那就要指定chunk_size=1024,大小自己设置, # 意思是下载一点写一点到磁盘。 for chunk in r.iter_content(chunk_size=1024): if chunk: temp_size += len(chunk) f.write(chunk) f.flush() #############花哨的下载进度部分############### done = int(50 * temp_size / total_size) # 调用标准输出刷新命令行,看到 回车符了吧 # 相当于把每一行重新刷新一遍 sys.stdout.write(" [%s%s] %d%%" % ('█' * done, ' ' * (50 - done), 100 * temp_size / total_size)) sys.stdout.flush() print() # 避免上面 回车符,执行完后需要换行了,不然都在一行显示 if __name__ == '__main__': link = r'https://api.gdc.cancer.gov/data/' UUID = r'2a4a3044-0b1a-4722-83ed-43ba5d6d25b0' # path是下载文件保存的路径 path = r'F:SYY empa.txt' # url是文件网址链接 url = os.path.join(link, UUID) # 调用上面下载函数即可 download(url, path)
demo04:
import sys import requests import os # 屏蔽warning信息 requests.packages.urllib3.disable_warnings() def download(url, file_path): # 第一次请求是为了得到文件总大小 r1 = requests.get(url, stream=True, verify=False) total_size = int(r1.headers['Content-Length']) # 这重要了,先看看本地文件下载了多少 if os.path.exists(file_path): temp_size = os.path.getsize(file_path) # 本地已经下载的文件大小 else: temp_size = 0 # 显示一下下载了多少 print(temp_size) print(total_size) # 核心部分,这个是请求下载时,从本地文件已经下载过的后面下载 headers = {'Range': 'bytes=%d-' % temp_size} # 重新请求网址,加入新的请求头的 r = requests.get(url, stream=True, verify=False, headers=headers) # 下面写入文件也要注意,看到"ab"了吗? # "ab"表示追加形式写入文件 with open(file_path, "ab") as f: for chunk in r.iter_content(chunk_size=1024): if chunk: temp_size += len(chunk) f.write(chunk) f.flush() ###这是下载实现进度显示#### done = int(50 * temp_size / total_size) sys.stdout.write(" [%s%s] %d%%" % ('█' * done, ' ' * (50 - done), 100 * temp_size / total_size)) sys.stdout.flush() print() # 避免上面 回车符 if __name__ == '__main__': link = r'https://api.gdc.cancer.gov/data/' UUID = r'2a4a3044-0b1a-4722-83ed-43ba5d6d25b0' path = r'F:SYY empa.txt' url = os.path.join(link, UUID) # 调用一下函数试试 download(url, path)
另外有
progressbar库:下载地址:https://pypi.python.org/pypi/progressbar2
简单用法1:
import time import progressbar p = progressbar.ProgressBar() N = 1000 for i in p(range(N)): time.sleep(0.01)
简单用法2:
import time import progressbar p = progressbar.ProgressBar() N = 1000 p.start(N) for i in range(N): time.sleep(0.01) p.update(i+1) p.finish()
- 高级点的用法(自己配置输出格式):
import time import progressbar bar = progressbar.ProgressBar(widgets=[ ' [', progressbar.Timer(), '] ', progressbar.Percentage(), ' (', progressbar.ETA(), ') ', ]) for i in bar(range(1000)): time.sleep(0.01)
输出格式:
[Elapsed Time: 0:00:10] 100% (Time: 0:00:10)
主要方式有如下几种,可自由搭配:
'Timer', # 计时器 'ETA', # 预计剩余时间 'AbsoluteETA', # 预计结束的绝对时间,耗时很长时使用较方便 'Percentage', # 百分比进度,30% 'SimpleProgress', # 计数进度,300/1000 'Counter', # 单纯计数 'Bar' # “#”号进度条
如:
import time import progressbar bar = progressbar.ProgressBar(widgets=[ progressbar.Percentage(), ' (', progressbar.SimpleProgress(), ') ', ' (', progressbar.AbsoluteETA(), ') ',]) for i in bar(range(1000)): time.sleep(0.01)
参考:https://blog.csdn.net/saltriver/article/details/53055942