Python编写一个优美的下载器


Posted in Python onApril 15, 2018

本文实例为大家分享了Python编写下载器的具体代码,供大家参考,具体内容如下

#!/bin/python3 
# author: lidawei 
# create: 2016-07-11 
# version: 1.0 
# 功能说明: 
#  从指定的URL将文件取回本地 
##################################################### 
 
import http.client 
import os 
import threading 
import time 
import logging 
import unittest 
from queue import Queue 
from urllib.parse import urlparse 
 
logging.basicConfig(level = logging.DEBUG, 
     format = '%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s', 
     datefmt = '%a, %d %b %Y %H:%M:%S', 
     filename = 'Downloader_%s.log' % (time.strftime('%Y-%m-%d')), 
     filemode = 'a') 
 
class Downloader(object): 
 '''''文件下载器''' 
 url = '' 
 filename = '' 
 
 def __init__(self, full_url_str, filename): 
  '''''初始化''' 
  self.url = urlparse(full_url_str) 
  self.filename = filename 
 
 def download(self): 
  '''''执行下载,返回True或False''' 
  if self.url == '' or self.url == None or self.filename == '' or self.filename == None: 
   logging.error('Invalid parameter for Downloader') 
   return False 
 
  successed = False 
  conn = None 
  if self.url.scheme == 'https': 
   conn = http.client.HTTPSConnection(self.url.netloc) 
  else: 
   conn = http.client.HTTPConnection(self.url.netloc) 
  conn.request('GET', self.url.path) 
  response = conn.getresponse() 
  if response.status == 200: 
   total_size = response.getheader('Content-Length') 
   total_size = (int)(total_size) 
   if total_size > 0: 
    finished_size = 0 
    file = open(self.filename, 'wb') 
    if file: 
     progress = Progress() 
     progress.start() 
     while not response.closed: 
      buffers = response.read(1024) 
      file.write(buffers) 
 
      finished_size += len(buffers) 
      progress.update(finished_size, total_size) 
      if finished_size >= total_size: 
       break 
     # ... end while statment 
     file.close() 
     progress.stop() 
     progress.join() 
    else: 
     logging.error('Create local file %s failed' % (self.filename)) 
    # ... end if statment 
   else: 
    logging.error('Request file %s size failed' % (self.filename)) 
   # ... end if statment 
  else: 
   logging.error('HTTP/HTTPS request failed, status code:%d' % (response.status)) 
  # ... end if statment 
  conn.close() 
 
  return successed 
 # ... end download() method 
# ... end Downloader class 
 
class DataWriter(threading.Thread): 
 filename = '' 
 data_dict = {'offset' : 0, 'buffers_byte' : b''} 
 queue = Queue(128) 
 __stop = False 
 
 def __init__(self, filename): 
  self.filename = filename 
  threading.Thread.__init__(self) 
 
 #Override 
 def run(self): 
  while not self.__stop: 
   self.queue.get(True, 1) 
 
 def put_data(data_dict): 
  '''''将data_dict的数据放入队列,data_dict是一个字典,有两个元素:offset是偏移量,buffers_byte是二进制字节串''' 
  self.queue.put(data_dict) 
 
 def stop(self): 
  self.__stop = True 
 
class Progress(threading.Thread): 
 interval = 1 
 total_size = 0 
 finished_size = 0 
 old_size = 0 
 __stop = False 
 
 def __init__(self, interval = 0.5): 
  self.interval = interval 
  threading.Thread.__init__(self) 
 
 #Override 
 def run(self): 
  # logging.info('  Total  Finished  Percent  Speed') 
  print('  Total  Finished  Percent  Speed') 
  while not self.__stop: 
   time.sleep(self.interval) 
   if self.total_size > 0: 
    percent = self.finished_size / self.total_size * 100 
    speed = (self.finished_size - self.old_size) / self.interval 
    msg = '%12d %12d %10.2f%% %12d' % (self.total_size, self.finished_size, percent, speed) 
    # logging.info(msg) 
    print(msg) 
 
    self.old_size = self.finished_size 
   else: 
    logging.error('Total size is zero') 
  # ... end while statment 
 # ... end run() method 
 
 def stop(self): 
  self.__stop = True 
 
 def update(self, finished_size, total_size): 
  self.finished_size = finished_size 
  self.total_size = total_size 
 
class TestDownloaderFunctions(unittest.TestCase): 
 
 def setUp(self): 
  print('setUp') 
 
 def test_download(self): 
  url = 'http://dldir1.qq.com/qqfile/qq/QQ8.4/18376/QQ8.4.exe' 
  filename = 'QQ8.4.exe' 
  dl = Downloader(url, filename) 
  dl.download() 
 
 def tearDown(self): 
  print('tearDown') 
 
if __name__ == '__main__': 
 unittest.main()

这是测试结果:

Python编写一个优美的下载器

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
简单使用Python自动生成文章
Dec 25 Python
Python运算符重载用法实例
May 28 Python
python中lambda()的用法
Nov 16 Python
10分钟教你用Python实现微信自动回复功能
Nov 28 Python
django小技巧之html模板中调用对象属性或对象的方法
Nov 30 Python
基于python实现的百度音乐下载器python pyqt改进版(附代码)
Aug 05 Python
pyinstaller 3.6版本通过pip安装失败的解决办法(推荐)
Jan 18 Python
详解Python中的分支和循环结构
Feb 11 Python
Django 返回json数据的实现示例
Mar 05 Python
keras的siamese(孪生网络)实现案例
Jun 12 Python
如何基于Python按行合并两个txt
Nov 03 Python
Python Numpy之linspace用法说明
Apr 17 Python
python实现音乐下载器
Apr 15 #Python
tensorflow 1.0用CNN进行图像分类
Apr 15 #Python
tensorflow学习笔记之mnist的卷积神经网络实例
Apr 15 #Python
tensorflow学习笔记之简单的神经网络训练和测试
Apr 15 #Python
Pytorch入门之mnist分类实例
Apr 14 #Python
pytorch构建网络模型的4种方法
Apr 13 #Python
Python输入二维数组方法
Apr 13 #Python
You might like
第五章 php数组操作
2011/12/30 PHP
php设计模式小结
2013/02/15 PHP
PHP中spl_autoload_register()和__autoload()区别分析
2014/05/10 PHP
php简单获取目录列表的方法
2015/03/24 PHP
Javascript在IE下设置innerHTML时出现未知的运行时错误的解决方法
2011/01/12 Javascript
裁剪字符串trim()自定义改进版
2013/04/10 Javascript
js四舍五入数学函数round使用实例
2014/05/09 Javascript
js判断手机和pc端选择不同执行事件的方法
2015/01/30 Javascript
javascript中动态函数用法实例分析
2015/05/14 Javascript
原生js实现addclass,removeclass,toggleclasss实例
2016/11/24 Javascript
Bootstrap框架安装使用详解
2017/01/21 Javascript
jQuery代码实现实时获取时间
2017/01/29 Javascript
js时间戳格式化成日期格式的多种方法介绍
2017/02/16 Javascript
微信小程序中显示html格式内容的方法
2017/04/25 Javascript
Vue和Bootstrap的整合思路详解
2017/06/30 Javascript
js实现拖拽上传图片功能
2017/08/01 Javascript
JS实现的杨辉三角【帕斯卡三角形】算法示例
2019/02/26 Javascript
详解如何在vue项目中使用layui框架及采坑
2019/05/05 Javascript
python实现的阳历转阴历(农历)算法
2014/04/25 Python
Python各类图像库的图片读写方式总结(推荐)
2018/02/23 Python
python微信跳一跳系列之棋子定位像素遍历
2018/02/26 Python
sublime python3 输入换行不结束的方法
2018/04/19 Python
python issubclass 和 isinstance函数
2019/07/25 Python
python定义类的简单用法
2020/07/24 Python
html5响应式开发自动计算fontSize的方法
2020/01/13 HTML / CSS
HTML5 FileReader对象的具体使用方法
2020/05/22 HTML / CSS
介绍一下mysql的日期和时间函数
2013/03/28 面试题
Unix控制后台进程都有哪些进程
2016/09/22 面试题
护理专业自荐信范文
2014/02/26 职场文书
路政管理求职信
2014/06/18 职场文书
人事局接收函
2015/01/30 职场文书
JS实现简单控制视频播放倍速的实例代码
2021/04/18 Javascript
css height属性中的calc方法详解
2021/06/03 HTML / CSS
java设计模式--七大原则详解
2021/07/21 Java/Android
Nginx下SSL证书安装部署步骤介绍
2021/12/06 Servers
使用ICOM IC-R9500接收机同时测评十台收音机中波接收性能
2022/05/10 无线电