# -*- coding=utf-8 -*-
import sys
import os
import os.path
import time
import urllib.request, urllib.parse, urllib.error
from threading import Thread local_proxies = {} class ThreadDownComplete:
def __init__(self, down_loaded):
self.down_loaded = down_loaded class ThreadDown(Thread, urllib.request.FancyURLopener):
def __init__(self, thread_name, url, filename, ranges=0, proxies={}):
Thread.__init__(self, name=thread_name)
urllib.request.FancyURLopener.__init__(self, proxies)
self.name = thread_name
self.url = url
self.filename = filename
self.ranges = ranges
self.down_loaded = 0
self.url_handler = None
self.one_time_size = 16384 # 16kByte/time
self.data_start_point = self.ranges[0]
self.data_end_point = self.ranges[1]
self.down_start_time = int(time.time())
self.recent_down_time = int(time.time())
self.stop = False
self.complete = False
self.download_loan = self.data_end_point - self.data_start_point
try:
self.down_loaded = os.path.getsize(self.filename)
except OSError:
self.down_loaded = 0
self.start_point = self.data_start_point + self.down_loaded if not self.complete_check():
self.data_check() def start_reset(self):
try:
os.remove(self.filename)
except:
pass self.down_loaded = 0
self.complete = False
self.stop = False
self.start_point = self.data_start_point def data_check(self):
if self.start_point > self.data_end_point:
print("Part %s has been down_loaded over.\n" % self.filename)
self.start_reset() def flow_check(self):
if self.down_loaded > self.download_loan + 1:
self.stop = False
return False
return True def complete_check(self):
if self.down_loaded == self.download_loan + 1:
self.complete = True
self.stop = True
return True
return False def down(self):
try:
return self.url_handler.read(self.one_time_size)
except:
return '' def __run(self): print("task %s will down_load from %d to %d" % (self.name, self.start_point, self.data_end_point))
self.addheader("Range", "bytes=%d-%d" % (self.start_point, self.data_end_point))
self.url_handler = self.open(self.url)
data = self.down() while not self.stop and not self.complete:
if data:
self.recent_down_time = int(time.time())
file_handler = open(self.filename, 'ab+')
file_handler.write(data)
file_handler.close()
self.down_loaded += len(data) if self.complete_check():
break
if not self.flow_check():
break data = self.down() def run(self): if self.complete:
return self.__run()
self.complete_check()
while not self.stop and not self.complete:
self.start_reset()
self.__run()
self.complete_check() def get_file_size(url, proxies={}):
url_handler = urllib.request.urlopen(url)
return int(url_handler.info()['Content-Length']) def split_blocks(total_size, block_number):
block_size = int(total_size / block_number)
ranges = []
for i in range(0, block_number - 1):
ranges.append((i * block_size, (i + 1) * block_size - 1))
ranges.append(((block_number - 1) * block_size, total_size - 1))
return ranges def is_live(tasks):
for index, task in enumerate(tasks):
if isinstance(task, ThreadDownComplete):
continue
if int(time.time()) - task.recent_down_time > 8:
thread_name = task.name
filename = task.filename
ranges = task.ranges
url = task.url
task.stop = True
tasks[index] = start_down_thread(thread_name, url, filename, ranges)
return True
if task.complete:
tasks[index] = ThreadDownComplete(task.down_loaded)
if task.is_alive():
return True
return False def start_down_thread(thread_name, url, filename, ranges):
task = ThreadDown(thread_name, url, filename, ranges)
task.setDaemon(True)
task.start()
return task def log(msg):
sys.stdout.write(msg)
sys.stdout.flush() def down_load(url, output, blocks=6, proxies=local_proxies):
down_file_size = get_file_size(url, proxies)
ranges = split_blocks(down_file_size, blocks) thread_name = ["thread_%d" % i for i in range(0, blocks)]
filename = [output + "_%d" % i for i in range(0, blocks)] tasks = []
for i in range(0, blocks):
tasks.append(start_down_thread(thread_name[i], url, filename[i], ranges[i])) while is_live(tasks):
down_loaded = sum([task.down_loaded for task in tasks])
process = down_loaded / float(down_file_size) * 100
log("\rfilesize:%d down_loaded:%d Completed:%.2f%%" % (down_file_size, down_loaded, process))
time.sleep(0.01) file_handler = open(output, 'wb+')
for i in filename:
f = open(i, 'rb')
file_handler.write(f.read())
f.close()
try:
os.remove(i)
pass
except:
pass file_handler.close() if os.path.getsize(output) == down_file_size:
log("\nCompleted\n")
else:
log("\nError\n") sys.exit(0) if __name__ == '__main__':
_url = "http://dldir1.qq.com/qqfile/qq/QQ7.9Light/14308/QQ7.9Light.exe"
down_load(_url, os.path.basename(_url), blocks=30, proxies={})

python多线程下载的更多相关文章

  1. python多线程下载文件

    从文件中读取图片url和名称,将url中的文件下载下来.文件中每一行包含一个url和文件名,用制表符隔开. 1.使用requests请求url并下载文件 def download(img_url, i ...

  2. python多线程下载ts文件

    # -*- coding: utf-8 -*- """ Created on Wed Aug 22 15:56:19 2018 @author: Administrato ...

  3. python多线程下载网页图片并保存至特定目录

    #!python3 #multidownloadXkcd.py - Download XKCD comics using multiple threads. import requests impor ...

  4. python线程使用场景 多线程下载

    http://blog.xiayf.cn/2015/09/11/parallelism-in-one-line http://python.jobbole.com/84327/ http://www. ...

  5. PYTHON文件多线程下载

    其实,在一般的文件编程中,这有两个概念要说明: 第一是,下载一个大文件,将这个大文件多为多线程. 第二是,下载N多小文件,将每个线程指定下载多个小文件. 现在实现的是多线程下载一个大文件. 今天完成了 ...

  6. Python之FTP多线程下载文件之分块多线程文件合并

    Python之FTP多线程下载文件之分块多线程文件合并 欢迎大家阅读Python之FTP多线程下载系列之二:Python之FTP多线程下载文件之分块多线程文件合并,本系列的第一篇:Python之FTP ...

  7. Python之FTP多线程下载文件之多线程分块下载文件

    Python之FTP多线程下载文件之多线程分块下载文件 Python中的ftplib模块用于对FTP的相关操作,常见的如下载,上传等.使用python从FTP下载较大的文件时,往往比较耗时,如何提高从 ...

  8. python爬取快手视频 多线程下载

    就是为了兴趣才搞的这个,ok 废话不多说 直接开始. 环境: python 2.7 + win10 工具:fiddler postman 安卓模拟器 首先,打开fiddler,fiddler作为htt ...

  9. python多线程爬虫+批量下载斗图啦图片项目(关注、持续更新)

    python多线程爬虫项目() 爬取目标:斗图啦(起始url:http://www.doutula.com/photo/list/?page=1) 爬取内容:斗图啦全网图片 使用工具:requests ...

随机推荐

  1. HDU 1728:逃离迷宫(BFS)

    http://acm.hdu.edu.cn/showproblem.php?pid=1728 逃离迷宫 Problem Description   给定一个m × n (m行, n列)的迷宫,迷宫中有 ...

  2. HDU 5724:Chess(博弈 + 状压)

    http://acm.hdu.edu.cn/showproblem.php?pid=5724 Chess Problem Description   Alice and Bob are playing ...

  3. C++中this指针的用法详解

    转自 http://blog.chinaunix.net/uid-21411227-id-1826942.html 1. this指针的用处: 一个对象的this指针并不是对象本身的一部分,不会影响s ...

  4. ZOJ 3866 - Cylinder Candy

    3866 - Cylinder Candy Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu ...

  5. 如何将vs2012项目的网站布置到iis上,实现内网访问

    1首先获得你本机的ip地址 可以通过命令行输入 ipconfig/all 2配置电脑的iis(前提是你已经安装了) 右击我的电脑选择管理 右键网站添加网页 会出来上面的对话框 选择直接的项目web路径 ...

  6. python学习笔记-day4笔记 常用内置函数与装饰器

    1.常用的python函数 abs             求绝对值 all               判断迭代器中所有的数据是否为真或者可迭代数据为空,返回真,否则返回假 any          ...

  7. qbxt十一系列二

    PA[题目描述]汉诺塔升级了:现在我们有N个圆盘和N个柱子,每个圆盘大小都不一样,大的圆盘不能放在小的圆盘上面,N个柱子从左到右排成一排.每次你可以将一个柱子上的最上面的圆盘移动到右边或者左边的柱子上 ...

  8. 怎样实现UIView的旋转

    首先创建界面,在viewDidLoad创建view以及button 相关代码如下 -(void)viewDidLoad { [super viewDidLoad]; viewDemo = [[UIVi ...

  9. Spark系列之二——一个高效的分布式计算系统

    1.什么是Spark? Spark是UC Berkeley AMP lab所开源的类Hadoop MapReduce的通用的并行计算框架,Spark基于map reduce算法实现的分布式计算,拥有H ...

  10. SqlSever基础 except 差集 前一个结果中不含有后一个结果的元素

    镇场诗:---大梦谁觉,水月中建博客.百千磨难,才知世事无常.---今持佛语,技术无量愿学.愿尽所学,铸一良心博客.------------------------------------------ ...