该源码为疯狂讲义多线程下载工具类, 可以使用,如果需要正式投产 建议添加相关异常处理.
from urllib.request import *
import threading
class DownUtil:
def __init__(self, path, targetfile, thread_num):
# need down file path
self.path = path
# Thread number
self.thread_num = thread_num
# save file path
self.targetfile = targetfile
# Threads
self.threads = []
self.file_size = 0;
def download(self):
# create request obj
req = Request(url=self.path,method='GET')
req.add_header('Accept','*/*')
req.add_header('CHarset','UTF-8')
req.add_header('Connection', 'Keep-Alive')
# open the source
f = urlopen(req)
# get file size
self.file_size = int(dict(f.headers).get('Content-Length',0))
f.close()
# current thread need down file size
current_part_size =self.file_size // self.thread_num + 1
for i in range(self.thread_num):
# record begin down file pos
start_pos = i* current_part_size
t = open(self.targetfile, 'wb')
t.seek(start_pos,0)
td = DownThread(self.path, start_pos, current_part_size, t)
self.threads.append(td)
# start Thread
td.start()
def get_complete_rate(self):
sum_size = 0
for i in range(self.thread_num):
sum_size += self.threads[i].length
return sum_size/self.file_size
class DownThread(threading.Thread):
def __init__(self, path, start_pos, current_part_size, current_part):
super().__init__()
self.path = path
# current thread down pos
self.start_pos = start_pos
# need down file size
self.current_part_size = current_part_size
# has downed file length
self.length =0
self.current_part = current_part
def run(self):
req = Request(url=self.path,method='GET')
req = Request(url=self.path, method='GET')
req.add_header('Accept', '*/*')
req.add_header('CHarset', 'UTF-8')
req.add_header('Connection', 'Keep-Alive')
# open the source
f = urlopen(req)
# skip pos
for i in range(self.start_pos):
f.read(1)
while self.length < self.current_part_size:
data = f.read(1024)
if data is None or len(data) <=0:
break
self.current_part.write(data)
self.length += len(data)
self.current_part.close()
f.close()
if __name__ =="__main__":
urlfile ="http://pic1.win4000.com/wallpaper/b/57e8cefd76fdc.jpg"
down = DownUtil(urlfile,"a.jpg",3)
down.download()
def show_process():
print('finished %.2f' % down.get_complete_rate())
global thTimer
if down.get_complete_rate() < 1 :
thTimer = threading.Timer(0.1,show_process)
thTimer.start()
thTimer = threading.Timer(0.1,show_process)
thTimer.start()