设为首页 加入收藏

TOP

Python3 多线程下载代码(三)
2015-12-15 23:09:06 来源: 作者: 【 】 浏览:3
Tags:Python3 线程 下载 代码
d Completed:%.2f%%\n' % (size, downloadsize,100)
? ? ? ? ? ? else:
? ? ? ? ? ? ? ? show = '\nSize is not mathed!\n'
? ? ? ? ? ? ? ? flag=False
? ? ? ? else:? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? #单线程下载的后续处理
? ? ? ? ? ? show = '\nTotal Size: %d\n'% downloaded
? ? ? ? sys.stdout.write(show)
? ? ? ? sys.stdout.flush()
? ? ? ? if flag:? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? #确认下载的临时文件没问题后将各文件整合为最终的目标文件
? ? ? ? ? ? print('Integrating files...')
? ? ? ? ? ? num=1
? ? ? ? ? ? while os.path.exists(output):? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? #防止与本地已存在文件重名
? ? ? ? ? ? ? ? fname,fext=os.path.splitext(output)
? ? ? ? ? ? ? ? if '('+str(num-1)+')'+fext in output:
? ? ? ? ? ? ? ? ? ? output = output.replace('('+str(num-1)+')'+fext,'('+str(num)+')'+fext)
? ? ? ? ? ? ? ? else:
? ? ? ? ? ? ? ? ? ? fname += '('+str(num)+')'
? ? ? ? ? ? ? ? ? ? output = fname+fext
? ? ? ? ? ? ? ? num +=1
? ? ? ? ? ? if len(filename) ==1 :? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? #单线程下载的话,直接将下载的文件重命名为目标文件即可
? ? ? ? ? ? ? ? os.rename(filename[0], output)
? ? ? ? ? ? else:? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? #多线程临时文件整合
? ? ? ? ? ? ? ? filehandle = open( output, 'wb+' )
? ? ? ? ? ? ? ? for i in filename:
? ? ? ? ? ? ? ? ? ? try:
? ? ? ? ? ? ? ? ? ? ? ? f = open( i, 'rb' )
? ? ? ? ? ? ? ? ? ? ? ? filehandle.write( f.read() )
? ? ? ? ? ? ? ? ? ? ? ? f.close()
? ? ? ? ? ? ? ? ? ? ? ? os.remove(i)
? ? ? ? ? ? ? ? ? ? except Exception as ex:
? ? ? ? ? ? ? ? ? ? ? ? print(ex)
? ? ? ? ? ? ? ? filehandle.close()
? ? ? ? ? ? if os.path.exists(output):
? ? ? ? ? ? ? ? print('Download Complete!')
? ? ? ? ? ? else:
? ? ? ? ? ? ? ? print('Failed to generate target file!')
? ? ? ? ? ? ? ? try:
? ? ? ? ? ? ? ? ? ? #os.remove(output)
? ? ? ? ? ? ? ? ? ? pass
? ? ? ? ? ? ? ? except:
? ? ? ? ? ? ? ? ? ? pass
? ? ? ? else:
? ? ? ? ? ? for i in filename:
? ? ? ? ? ? ? ? try:
? ? ? ? ? ? ? ? ? ? os.remove(i)
? ? ? ? ? ? ? ? ? ? pass
? ? ? ? ? ? ? ? except:
? ? ? ? ? ? ? ? ? ? pass
? ? ? ? ? ? print('Download Failed!')
? ? ? ? ? ? pass
? ? ? ? print('Consuming: {}\n'.format(consuming))? ? ? ? ? ? ? ? ? ? ? ? #输出耗时
    else:
        print('Failed to retrieve resource information!')
        sys.exit()
def main(argv):? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? #处理传入参数,使用了getopt模块,另外有一个更强大的处理传入参数的模块optparse
? ? try:
? ? ? ? options,args=getopt.getopt(argv,'hu:f:n:p:',['help','url=','target=','num=','proxy='])
? ? except Exception as ex:
? ? ? ? print(ex)
? ? ? ? sys.exit()
? ? num = 2
? ? url,target,proxies= '','',''


? ? url = 'http://www.pygtk.org/dist/pygtk2-tut.pdf'
? ? target = '/home/maple/Desktop'
? ? #proxies = 'http://127.0.0.1:8087'
? ? #proxies={}
? ? for name, value in options:
? ? ? ? if name in ('-h','--help'):
? ? ? ? ? ? print('No Help ^^')
? ? ? ? ? ? sys.exit()
? ? ? ? if name in ('-u','--url'):
? ? ? ? ? ? url = value
? ? ? ? if name in ('-t','--target'):
? ? ? ? ? ? target = value
? ? ? ? if name in ('-n','--num'):
? ? ? ? ? ? num = int(value)
? ? ? ? if name in ('-p','--proxy'):
? ? ? ? ? ? proxies=value
? ? #check args
? ? download(url,target,num,proxies)



if __name__ == '__main__':
? ? main(sys.argv[1:])


这段代码在异常处理方面写得有些乱,没怎么关心异常处理,需要时再改吧


另外多线程下载时,如果使用了代理,会导致下载到的文件与服务器提供的文件大小不符。从而下载失败。我使用的是GoAgent,代理服务器会自动对目标文件进行多线程下载,无视程序指定的下载字节范围。第一个线程就会下载到完整的文件,其他线程会下载冗余内容。没有找到规范的处理办法。变通的处理办法有2种:


1、将使用了代理的多线程下载强制指定为单线程下载


2、不进行文件大小的校验,将多线程下载的0号临时文件重命名为目标文件,其他临时文件删除。


两种方法实现都很简单,但是破坏代码的整体逻辑。没有加入代码中。运行截图:



下面关于Python的文章您也可能喜欢,不妨看看:


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

评论

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