之前分享过的一片爬取网页视频的脚本,虽然有“下载开始”和“下载结束”的提示信息,但是在下载的过程中,总有一种莫名的焦虑。
在下载的过程中,添加下载进度的提示信息,即使用进度条展示下载的进度,在等待下载结束的过程中,焦躁的内心感觉踏实多了。
针对进度条方法简单说两句:
1、当进度条代表的全部数据比较大时,就可能出现一个进度“#”带表的数据量很大,进度条变化不明显的问题。(所以在方法中添加了chunk()方法,返回每个“#”代表的数据量。)
# coding:utf-8
class ProcessBar(object):
def __init__ ( self, number=50, decimal=2):
"""
:param number: # 号的个数
:param decimal: 你保留的保留小数位
"""
self.decimal = decimal
self.number = number
def __call__ ( self, now, total ):
# 1. 获取当前的百分比数
percentage = self.percentage_number(now, total)
# print percentage, now, total
# 2. 根据 现在百分比计算
well_num = int(percentage * self.number)
# 3. 打印字符进度条
progress_bar_num = self.progress_bar(well_num)
# 4. 完成的进度条
result = '{0} {1:>5.0%}'.format(progress_bar_num, percentage)
print result
def percentage_number ( self, now, total ):
"""
计算百分比
:param now: 现在的数
:param total: 总数
:return: 根据指定的精度返回进度
"""
return round(now / total , 2)
def progress_bar ( self, num ):
"""
显示进度条位置
:param num: 拼接的 “#” 号的
:return: 返回的结果当前的进度条
"""
# 1. "#" 号个数
well_num = "#" * num
# 2. 空格的个数
space_num = " " * (self.number - num)
return '[%s%s]' % (well_num, space_num)
def Chunk( self, total):
"""
返回每个#代表的所代表的大小
:param total: 全部大小
:return: 每个#的进度量
"""
chunk = round(total /self.number, self.decimal)
return chunk
if __name__ == '__main__':
# 设置进度条的#个数为100个,每个#代表实际数据精度
bar = ProcessBar(100,2)
# print bar.number,bar.decimal
# 进度条代表的数值
total = 10000.0
# 每个#代表实际数据
chunkbar = bar.Chunk(total)
# 已完成部分loaded,累积的增量数据increment
loaded = increment = 0
# 循环完成数据获取
for i in range(1,10001):
# 累积每次完成量
increment += 1
# 保证每完成 # 数据量获取后,进行一次打印
if increment < chunkbar and (loaded + increment) != total:
continue
loaded += increment
bar(loaded, total)
# 完成一次累积量后,清空重新计算
increment = 0
看一下运行的效果:
2、在之前爬取视频的download_file(url,path)方法中添加进度条对象的调用。
def download_file(url, path):
'''
下载视频
:param url: 视频地址
:param path: 保存路径
'''
with requests.get(url, stream=True) as r:
chunk_size = 1024
content_size = float(r.headers[ 'content-length' ])
print '下载开始'
with open(path, "wb") as f:
# 添加进度条方法的调用
loaded = increment = 0
bar = ProcessBar(50,2)
chunkbar = bar.Chunk(content_size)
for chunk in r.iter_content(chunk_size=chunk_size):
increment += len(chunk)
if increment < chunkbar and ( loaded + increment ) != content_size :
continue
loaded += increment
increment = 0
bar(loaded, content_size)
f.write(chunk)
print '下载结束'
按照之前的方法重新调用爬取文件,一点没有改变哟:
if __name__ == '__main__':
url = 'http://www.vdonghua.cn/info/61.html' # 页面地址
VedioUrl = GetData(url)
download_file(VedioUrl,'61.mp4')# 保存视频至指定位置
运行效果如下图,是不是要更加直观一些呢?