python进度条实现

之前分享过的一片爬取网页视频的脚本,虽然有“下载开始”和“下载结束”的提示信息,但是在下载的过程中,总有一种莫名的焦虑。
在下载的过程中,添加下载进度的提示信息,即使用进度条展示下载的进度,在等待下载结束的过程中,焦躁的内心感觉踏实多了。

感谢如梦dream老师的文章分享。

针对进度条方法简单说两句:

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

看一下运行的效果:
python进度条实现_第1张图片
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')# 保存视频至指定位置

运行效果如下图,是不是要更加直观一些呢?
python进度条实现_第2张图片

你可能感兴趣的:(common)