Python實現多線程下載檔案的代碼執行個體

來源:互聯網
上載者:User
實現簡單的多線程下載,需要關注如下幾點:
1.檔案的大小:可以從reponse header中提取,如“Content-Length:911”表示大小是911位元組
2.任務拆分:指定各個線程下載的檔案的哪一塊,可以通過request header中添加“Range: bytes=300-400”(表示下載300~400byte的內容),注意可以請求的檔案的range是[0, size-1]位元組的。
3.下載檔案的彙總:各個線程將自己下載的檔案塊儲存為臨時檔案,所有線程都完成後,再將這些臨時檔案按順序彙總寫入到最終的一個檔案中。

實現代碼:
複製代碼 代碼如下:


#!/usr/bin/python
# -*- coding: utf-8 -*-
# filename: paxel.py
# FROM: http://jb51.net/code/view/58/full/
# Jay modified it a little and save for further potential usage.

'''It is a multi-thread downloading tool

It was developed following axel.
Author: volans
E-mail: volansw [at] gmail.com
'''

import sys
import os
import time
import urllib
from threading import Thread

# in case you want to use http_proxy
local_proxies = {'http': 'http://131.139.58.200:8080'}


class AxelPython(Thread, urllib.FancyURLopener):
'''Multi-thread downloading class.

run() is a vitural method of Thread.
'''
def __init__(self, threadname, url, filename, ranges=0, proxies={}):
Thread.__init__(self, name=threadname)
urllib.FancyURLopener.__init__(self, proxies)
self.name = threadname
self.url = url
self.filename = filename
self.ranges = ranges
self.downloaded = 0

def run(self):
'''vertual function in Thread'''
try:
self.downloaded = os.path.getsize(self.filename)
except OSError:
#print 'never downloaded'
self.downloaded = 0

# rebuild start poind
self.startpoint = self.ranges[0] + self.downloaded

# This part is completed
if self.startpoint >= self.ranges[1]:
print 'Part %s has been downloaded over.' % self.filename
return

self.oneTimeSize = 16384 # 16kByte/time
print 'task %s will download from %d to %d' % (self.name, self.startpoint, self.ranges[1])

self.addheader("Range", "bytes=%d-%d" % (self.startpoint, self.ranges[1]))
self.urlhandle = self.open(self.url)

data = self.urlhandle.read(self.oneTimeSize)
while data:
filehandle = open(self.filename, 'ab+')
filehandle.write(data)
filehandle.close()

self.downloaded += len(data)
#print "%s" % (self.name)
#progress = u'\r...'

data = self.urlhandle.read(self.oneTimeSize)


def GetUrlFileSize(url, proxies={}):
urlHandler = urllib.urlopen(url, proxies=proxies)
headers = urlHandler.info().headers
length = 0
for header in headers:
if header.find('Length') != -1:
length = header.split(':')[-1].strip()
length = int(length)
return length


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 paxel(url, output, blocks=6, proxies=local_proxies):
''' paxel
'''
size = GetUrlFileSize(url, proxies)
ranges = SpliteBlocks(size, blocks)

threadname = ["thread_%d" % i for i in range(0, blocks)]
filename = ["tmpfile_%d" % i for i in range(0, blocks)]

tasks = []
for i in range(0, blocks):
task = AxelPython(threadname[i], url, filename[i], ranges[i])
task.setDaemon(True)
task.start()
tasks.append(task)

time.sleep(2)
while islive(tasks):
downloaded = sum([task.downloaded for task in tasks])
process = downloaded / float(size) * 100
show = u'\rFilesize:%d Downloaded:%d Completed:%.2f%%' % (size, downloaded, process)
sys.stdout.write(show)
sys.stdout.flush()
time.sleep(0.5)

filehandle = open(output, 'wb+')
for i in filename:
f = open(i, 'rb')
filehandle.write(f.read())
f.close()
try:
os.remove(i)
pass
except:
pass

filehandle.close()

if __name__ == '__main__':
url = 'http://dldir1.qq.com/qqfile/QQforMac/QQ_V3.1.1.dmg'
output = 'download.file'
paxel(url, output, blocks=4, proxies={})
  • 聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.