之前分享過的一片爬取網頁視頻的腳本,雖然有“下載開始”和“下載結束”的提示信息,但是在下載的過程中,總有一種莫名的焦慮。
在下載的過程中,添加下載進度的提示信息,即使用進度條展示下載的進度,在等待下載結束的過程中,焦躁的內心感覺踏實多了。
針對進度條方法簡單說兩句:
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')# 保存視頻至指定位置
運行效果如下圖,是不是要更加直觀一些呢?