设为首页 加入收藏

TOP

Python3 多线程下载代码(二)
2015-12-15 23:09:06 来源: 作者: 【 】 浏览:4
Tags:Python3 线程 下载 代码
(name,ext)=('Unknown','')
? ? if 'Content-Length' in headers:? ? ? ? ? #获取文件长度,如果获取失败,则只能使用单线程下载
? ? ? ? length=int(headers.get('Content-Length'))
? ? else:
? ? ? ? length=-1? ? ? ? ? ?
? ? (type, kind)=headers.get('Content-Type').split('/') #获取文件类型,备用
? ? infos=[(name,ext),(type,kind),length]
? ? return infos


def SpliteBlocks(totalsize, blocknumber):? #根据指定的线程数参数和获取到的文件长度划分各线程的下载范围
? ? blocksize = totalsize//blocknumber
? ? ranges = []
? ? for i in range(0, blocknumber-1):
? ? ? ? ranges.append((i*blocksize, i*blocksize +blocksize - 1))
? ? ranges.append(( blocksize*(blocknumber-1), totalsize -1 ))


? ? return ranges
def islive(tasks):? ? ? ? ? ? ? ? ? ? ? ? #检查各线程是否全部下载完成
? ? for task in tasks:
? ? ? ? if task.isAlive():
? ? ? ? ? ? return True
? ? return False


def download(url, target=os.getcwd(), blocks=6, proxies=local_proxies):? ? ? ? ? ? ?


? ? flag=True
? ? print('Retrieving resource information...')


? ? url=urllib.parse.quote(url,safe='/%&@=+?$;,:')? ? ? ? #将提供的url编码,非英文字符将被编码为标准格式
? ? try:
? ? ? ? infos=GetUrlFileInfo(url,proxies)? ? ? ? ? ? ? ? ? ? ? ? ? ? #获取文件信息
? ? except Exception as ex:
? ? ? ? print(ex)
? ? ? ? flag=False
? ? if flag: 
? ? ? ? if not os.path.exists(target):
? ? ? ? ? ? os.makedirs(target)
? ? ? ? size=infos[2]? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? #获取到的文件大小
? ? ? ? output=os.path.join(target,''.join(infos[0]))? ? ? ? #根据获取到的文件名和指定的保存目录生成完整路径
? ? ? ? type=infos[1][0]


? ? ? ? starttime=time.time()? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? #开始计时
? ? ? ? print('Infomation:')
? ? ? ? print('FileName:{0}? ? FileType:{1}? ? FileLength:{2}'.format(''.join(infos[0]),'/'.join(infos[1]),infos[2] if int(infos[2]) > 0 else 'Unknown'))? #打印获取到的文件信息
? ? ? ? if size > 0:? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? #size大于0表示成功获取文件长度,可以进行多线程下载
? ? ? ? ? ? print('Starting multithread download...')
? ? ? ? ? ? ranges = SpliteBlocks( size, blocks )
? ? ? ? else:? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? #只能单线程下载,线程数置1,ranges置空,
? ? ? ? ? ? print('Starting single thread download...')
? ? ? ? ? ? ranges=()
? ? ? ? ? ? blocks=1
? ? ? ? threadname = [ infos[0][0]+"_thread_%d" % i for i in range(0, blocks) ]? ? ? ? #生成线程名
? ? ? ? filename = [ infos[0][0]+ "_tmpfile_%d" % i for i in range(0, blocks) ]? ? ? ? ? ? #生成各线程的临时文件名
? ? ? ? tasks = []? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
? ? ? ? for i in range(0,blocks):? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? #生成下载线程,设置为后台线程后启动,将线程加入到线程列表中
? ? ? ? ? ? task = Maple( threadname[i], url, filename[i], ranges[i] if ranges else ranges,proxies)
? ? ? ? ? ? task.setDaemon( True )
? ? ? ? ? ? task.start()
? ? ? ? ? ? tasks.append( task )


? ? ? ? time.sleep( 1 )
? ? ? ? downloaded = 0
? ? ? ? while islive(tasks):? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? #统计线程列表中各线程的状态,输出下载进度
? ? ? ? ? ? downloaded = sum( [task.downloaded for task in tasks] )
? ? ? ? ? ? if size > 0:
? ? ? ? ? ? ? ? process = downloaded/float(size)*100
? ? ? ? ? ? ? ? show = '\rFilesize:%d Downloaded:%d Completed:%.2f%%' % (size, downloaded, process)
? ? ? ? ? ? else:
? ? ? ? ? ? ? ? show = '\rDownloaded:%d ' % downloaded
? ? ? ? ? ? sys.stdout.write(show)
? ? ? ? ? ? sys.stdout.flush()
? ? ? ? ? ? time.sleep( 0.2 )
? ? ? ? endtime=time.time()? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? #下载完成后停止计时
? ? ? ? consuming=Sec2Time(endtime-starttime)
? ? ? ? if size > 0:? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? #多线程下载的后续处理
? ? ? ? ? ? downloadsize = 0
? ? ? ? ? ? for i in filename:
? ? ? ? ? ? ? ? downloadsize += os.path.getsize(i)
? ? ? ? ? ? if downloadsize == size:
? ? ? ? ? ? ? ? show = '\rFilesize:%d Downloaded:%

首页 上一页 1 2 3 下一页 尾页 2/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇C语言查看各种数据类型的size 下一篇Java JNI的使用基础

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: