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分析nignx访问日志脚本分享
Feb 26 Python
在Django的视图中使用form对象的方法
Jul 18 Python
Python中几种导入模块的方式总结
Apr 27 Python
Python使用matplotlib实现基础绘图功能示例
Jul 03 Python
python跳过第一行快速读取文件内容的实例
Jul 12 Python
python生成九宫格图片
Nov 19 Python
python调用opencv实现猫脸检测功能
Jan 15 Python
Python爬虫——爬取豆瓣电影Top250代码实例
Apr 17 Python
Python单例模式的四种创建方式实例解析
Mar 04 Python
Python如何发送与接收大型数组
Aug 07 Python
python如何写个俄罗斯方块
Nov 06 Python
秀!学妹看见都惊呆的Python小招数!【详细语言特性使用技巧】
Apr 27 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
jquery ajax 同步异步的执行示例代码
2010/06/23 Javascript
jQuery .tmpl(), .template()学习资料小结
2011/07/18 Javascript
JavaScript中document对象使用详解
2015/01/06 Javascript
Javascript中的getUTCHours()方法使用详解
2015/06/10 Javascript
理解javascript中的原型和原型链
2015/07/30 Javascript
基于JS实现简单的样式切换效果代码
2015/09/04 Javascript
JavaScript实现标题栏文字轮播效果代码
2015/10/24 Javascript
给easyui datebox扩展一个清空的实例
2016/11/09 Javascript
基于jquery二维码生成插件qrcode
2017/01/07 Javascript
js 原型对象和原型链理解
2017/02/09 Javascript
vue router动态路由下让每个子路由都是独立组件的解决方案
2018/04/24 Javascript
最简单的vue消息提示全局组件的方法
2019/06/16 Javascript
Vue 实现从小到大的横向滑动效果详解
2019/10/16 Javascript
angular8和ngrx8结合使用的步骤介绍
2019/12/01 Javascript
JavaScript的console命令使用实例
2019/12/03 Javascript
微信小程序scroll-view隐藏滚动条的方法详解
2020/03/25 Javascript
Vue中正确使用Element-UI组件的方法实例
2020/10/13 Javascript
vue中echarts的用法及与elementui-select的协同绑定操作
2020/11/17 Vue.js
[01:30:15]DOTA2-DPC中国联赛 正赛 Ehome vs Aster BO3 第二场 2月2日
2021/03/11 DOTA
Python splitlines使用技巧
2008/09/06 Python
python命令行参数解析OptionParser类用法实例
2014/10/09 Python
Python随机生成均匀分布在三角形内或者任意多边形内的点
2017/12/14 Python
python matplotlib中文显示参数设置解析
2017/12/15 Python
python高阶爬虫实战分析
2018/07/29 Python
python 递归深度优先搜索与广度优先搜索算法模拟实现
2018/10/22 Python
python支付宝支付示例详解
2019/08/22 Python
python numpy 反转 reverse示例
2019/12/04 Python
Python监听键盘和鼠标事件的示例代码
2020/11/18 Python
简单html5代码获取地理位置
2014/03/31 HTML / CSS
美国校园市场:OCM
2017/06/08 全球购物
《小壁虎借尾巴》教学反思
2014/02/16 职场文书
政风行风整改报告
2014/11/06 职场文书
毕业酒会致辞
2015/07/29 职场文书
创业计划书之宠物店
2019/09/19 职场文书
mysql如何能有效防止删库跑路
2021/10/05 MySQL
MySQL数据库Innodb 引擎实现mvcc锁
2022/05/06 MySQL