python带进度的文件下载函数
1、普通下载
①对于非文本请求,我们可以通过 Response 对象的 content 属性以字节的方式访问请求响应体。
【注意】这种模式只能下载小文件。因为在这种模式下,从服务器接收到的数据是一直储存在内存中,只有当 write 时才写入硬盘,如果文件很大,那么所占用的内存也是很大的。
②下面将一张网络上的图片下载到本地并保存(文件名不变):
import requests url = 'http://www.hangge.com/blog/images/logo.png' response = requests.get(url) # 此时在内存为response响应对象开辟空间,从服务器返回的数据也是一直存储在内存中中 with open("logo.png", "wb") as code: code.write(response.content) # 调用write方法时将内存中的二进制数据写入硬盘
2.流式下载 即边下载边保存。这种方式适合用来下载大文件。
import requests url = 'http://www.hangge.com/blog/images/logo.png' r = requests.get(url, stream=True) with open("logo.png", "wb") as f: for bl in r.iter_content(chunk_size=1024): if bl: f.write(bl)
3.带进度的文件下载
如果文件体积很大,下载时我们最好能实时显示当前的下载进度。
为方便使用应该封装一个下载方法(内部同样使用流式下载的方式)
import requests from contextlib import closing # 文件下载器 def down_load(file_url, file_path): with closing(requests.get(file_url, stream=True)) as response: chunk_size = 1024 # 单次请求最大值 content_size = int(response.headers['content-length']) # 内容体总大小 data_count = 0 with open(file_path, "wb") as file: for data in response.iter_content(chunk_size=chunk_size): file.write(data) data_count = data_count + len(data) now_jd = (data_count / content_size) * 100 print("\r 文件下载进度:%d%%(%d/%d) - %s" % (now_jd, data_count, content_size, file_path), end=" ") if __name__ == '__main__': fileUrl = 'http://www.hangge.com/hangge.zip' # 文件链接 filePath = "logo.zip" # 文件路径 down_load(fileUrl, filePath)
4.带下载速度显示的文件下载
import requests import time from contextlib import closing # 文件下载器 def down_load(file_url, file_path): start_time = time.time() # 文件开始下载时的时间 with closing(requests.get(file_url, stream=True)) as response: chunk_size = 1024 # 单次请求最大值 content_size = int(response.headers['content-length']) # 内容体总大小 data_count = 0 with open(file_path, "wb") as file: for data in response.iter_content(chunk_size=chunk_size): file.write(data) data_count = data_count + len(data) now_jd = (data_count / content_size) * 100 speed = data_count / 1024 / (time.time() - start_time) print("\r 文件下载进度:%d%%(%d/%d) 文件下载速度:%dKB/s - %s" % (now_jd, data_count, content_size, speed, file_path), end=" ") if __name__ == '__main__': fileUrl = 'http://www.hangge.com/hangge.zip' # 文件链接 filePath = "hangge.zip" # 文件路径 down_load(fileUrl, filePath)