Python3 多线程下载代码,貌似原版源自Axel这个多线程下载工具。
'''
Created on 2014-10-24
@author: Maple
'''
import sys
import os
import time
import getopt
import urllib.request
import urllib.parse
from threading import Thread
#===============================================================================
# def download(url, output=os.getcwd(), blocks=6, proxies=local_proxies)
# output:输出文件路径,默认为当前路径
# blocks:线程数
# proxies:代理地址
#===============================================================================
local_proxies = {}#代理地址
class Maple(Thread):
version = "Mozilla/5.0"
def __init__(self, threadname, url, filename, ranges=0, proxies={}):
Thread.__init__(self, name=threadname)
self.name = threadname
self.url = url
self.proxies = proxies
self.filename = filename
self.ranges = ranges
self.downloaded = 0
def run(self):
try:
self.downloaded = os.path.getsize( self.filename ) #获取已下载的文件字节块块,支持断点续传
except OSError:
#print 'never downloaded'
self.downloaded = 0
opener=GetUrlOpener(self.proxies) #根据代理参数生成相应的url opener
if self.ranges: #ranges为线程需要下载的文件块的字节范围
# rebuild start poind
self.startpoint = self.ranges[0] + self.downloaded #从已下载字节块后的位置开始下载
# This part is completed
if self.startpoint >= self.ranges[1]:
self.downloaded = self.ranges[1] - self.ranges[0]
print ('Part %s has been downloaded over.' % self.filename)
return
opener.addheaders=[('Range','bytes={}-{}'.format(self.startpoint, self.ranges[1])),('User-agent','Mozilla/5.0')] #添加请求头部内容,仅下载指定范围的字节,伪装成浏览器请求
print ('task %s will download from %d to %d' % (self.name, self.startpoint+1, self.ranges[1]+1))
else: #ranges未指定(文件大小未知,无法切割),从已下载字节块后的位置开始下载剩余全部字节
self.startpoint = self.downloaded
opener.addheaders=[('Range','bytes={}-'.format(self.startpoint)),('User-agent','Mozilla/5.0')]
self.fetchsize = 16384 #每次读取的字节数
self.urlhandle = opener.open(self.url) #打开文件地址
data = self.urlhandle.read( self.fetchsize )
while data: #循环读取数据写入临时文件,并更新已下载字节数
filehandle = open( self.filename, 'ab+' )
filehandle.write( data )
filehandle.close()
self.downloaded += len( data )
data = self.urlhandle.read( self.fetchsize )