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 31 Python
Python多层嵌套list的递归处理方法(推荐)
Jun 08 Python
python实现rsa加密实例详解
Jul 19 Python
Python数据拟合与广义线性回归算法学习
Dec 22 Python
Python子类继承父类构造函数详解
Feb 19 Python
Python 图像对比度增强的几种方法(小结)
Sep 25 Python
Pytorch Tensor基本数学运算详解
Dec 30 Python
Python 字典中的所有方法及用法
Jun 10 Python
Python如何使用27行代码绘制星星图
Jul 20 Python
Python 可视化神器Plotly详解
Dec 26 Python
python Scrapy框架原理解析
Jan 04 Python
PyQt5 显示超清高分辨率图片的方法
Apr 11 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
CI框架Session.php源码分析
2014/11/03 PHP
学习php设计模式 php实现原型模式(prototype)
2015/12/07 PHP
ThinkPHP连接Oracle数据库
2016/04/22 PHP
php简单实现短网址(短链)还原的方法(测试可用)
2016/05/09 PHP
PHP通过引用传递参数用法分析
2016/12/01 PHP
js 数组的for循环到底应该怎么写?
2010/05/31 Javascript
jQuery的实现原理的模拟代码 -5 Ajax
2010/08/07 Javascript
JavaScript实现统计文本框Textarea字数增强用户体验
2012/12/21 Javascript
jquery 多行文本框(textarea)高度变化
2013/07/03 Javascript
解决ueditor jquery javascript 取值问题
2014/12/30 Javascript
jQuery EasyUI datagrid实现本地分页的方法
2015/02/13 Javascript
js生成验证码并直接在前端判断
2015/05/15 Javascript
Vue实现选择城市功能
2017/05/27 Javascript
基于JavaScript实现表格滚动分页
2017/11/22 Javascript
React Native 截屏组件的示例代码
2017/12/06 Javascript
JS中Map和ForEach的区别
2018/02/05 Javascript
JavaScript如何对图片进行黑白化
2018/04/10 Javascript
vue.js项目 el-input 组件 监听回车键实现搜索功能示例
2018/08/25 Javascript
记录一次完整的react hooks实践
2019/03/11 Javascript
JS隐藏号码中间4位代码实例
2019/04/09 Javascript
vue双向绑定数据限制长度的方法
2019/11/04 Javascript
小程序使用分包的示例代码
2020/03/23 Javascript
Python列表(list)常用操作方法小结
2015/02/02 Python
详解Python中dict与set的使用
2015/08/10 Python
谈谈如何手动释放Python的内存
2016/12/17 Python
python difflib模块示例讲解
2017/09/13 Python
python读取csv和txt数据转换成向量的实例
2019/02/12 Python
Pyqt5 实现跳转界面并关闭当前界面的方法
2019/06/19 Python
意大利一家专营包包和配饰的网上商店:Borse Last Minute
2019/08/26 全球购物
幼儿园母亲节活动方案
2014/03/10 职场文书
幸福家庭事迹材料
2014/12/20 职场文书
幼儿园中班教师个人总结
2015/02/05 职场文书
2016年读书月活动总结范文
2016/04/06 职场文书
小学秋季运动会加油口号及加油稿
2019/08/19 职场文书
导游词之海南-南湾猴岛
2019/10/12 职场文书
排查Tomcat进程假死的问题
2022/05/06 Servers