我实现了一个函数, 代码如下:
def download_file_from_url(url, save_path='', callback:callable = None):'''下载文件, 并保存到save_path指定的位置url: 形如'http://www.tdx.com.cn/products/data/data/vipdoc/shlday.zip' 或者'http://www.tdx.com.cn/products/data/data/vipdoc/szlday.zip'save_path: 保存的目标路径, 形如: 'c:/abc'callback: 回调函数, 用于实时报告进度的, void f(context:dict)context形如: {}'''target_filename = url.split('/')[-1] # 取出url的结尾作为文件名if save_path == '': save_path = get_main_path() # 如果没有指定保存路径, 则使用默认路径full_path = os.path.join(save_path, target_filename) # 拼接得到全路径with requests.get(url, stream=True) as fget:# 此时只有响应头被下载file_size = int(fget.headers["Content-Length"])context = {} # 回调函数上下文信息, 用于记录下载进度context['file_name'] = full_pathcontext['file_size'] = round(file_size/(1024**2),2) # 单位: Mb# 每次读取100k字节chunk_size = 100*1024file_done = 0with open(full_path, "wb") as fw:for chunk in fget.iter_content(chunk_size):fw.write(chunk)file_done += chunk_sizepercent = file_done / file_sizecontext['download_size'] = round(file_done/(1024**2),2) # 单位: Mbcontext['download_percent'] = round(percent,2) # 形如: 0.34, 表示百分比进度if callback is not None: callback(context) # 回调函数
- 使用示例
里面具体的网站可以替换为自己需要的:
import Common
# '\r'参数可以使打印信息保持在同一行
def _打印进度(context): print(context,end='\r')
url = 'http://xxx.xxx.xxx/shlday.zip'
Common.download_file_from_url(url,callback=_打印进度)
如下图所示: