#coding:utf-8

# windows中测试不通过,下载的图片不完整
# 通过多线程下载图片

import requests
import threading

class downloader(object):
    def __init__(self):
        # self.url = 'http://f1.topitme.com/1/eb/96/112730204208796eb1o.jpg'
        # mysql source package
        # self.url = 'http://mirrors.sohu.com/mysql/MySQL-5.6/mysql-5.6.35.tar.gz'
        # yangmi
        self.url = 'https://imgsa.baidu.com/baike/c0%3Dbaike116%2C5%2C5%2C116%2C38/sign=18d31e2c6c380cd7f213aabfc02dc651/2e2eb9389b504fc27dcf5199ecdde71191ef6d9e.jpg'
        
        # self.name = 'mysql-5.6.35.tar.gz'
        self.name = 'yangmi.jpg'
        self.num = 5


    def get_img(self, r):
        # 获取图片的分段位置,并记录seek值(分段后的起始位置)开始写入系统
        _request = requests.get(self.url, headers = {'Range':'bytes=%s-%s' % r})
        self.fd.seek(r[0])
        self.fd.write(_request.content)
        print 'success %s-%s' % r

    def get_range(self):
        r = requests.head(self.url)
        headers = r.headers
        # 获取图片的大小
        image_size = int(headers['Content-Length'])
        # print [image_size]
        # 分为5段(即开启5个线程下载图片)
        offset = image_size / self.num
        print image_size
        range_list = []

        # 将图片分为 num(5)段
        for i in range(self.num):
            if i == self.num - 1:
                range_list.append((offset*i, ''))
            else:
                range_list.append((offset*i, offset*(i + 1)))
        return range_list


    def download(self):
        range_list = self.get_range()
        self.fd = open(self.name, 'w')
        n = 0
        ths = []
        # 创建线程
        for r in range_list:
            # self.get_img(r)
            # 开启多线程下载
            th = threading.Thread(target=self.get_img(r), args = r)
            th.start()
            print 'thread%d' % n
            n += 1
            ths.append(th)
            
        # 线程等待
        for r in ths:
            r.join()  

        self.fd.close()
        print 'download success'


if __name__ == "__main__":
    d = downloader()
    d.download()

 

普通分段下载

#coding:utf-8

# windows中测试不通过,下载的图片不完整
# 分段下载图片
import requests
from decimal import Decimal

class downloader(object):
    def __init__(self):
        self.url = 'https://ss2.baidu.com/6ONYsjip0QIZ8tyhnq/it/u=4241609126,773789288&fm=173&s=E42EB6570862D211C87C4CEE0300A02A&w=500&h=333&img.JPG'
        # yangmi
        # self.url = 'https://imgsa.baidu.com/baike/c0%3Dbaike116%2C5%2C5%2C116%2C38/sign=18d31e2c6c380cd7f213aabfc02dc651/2e2eb9389b504fc27dcf5199ecdde71191ef6d9e.jpg'
        
        self.name = 'bizhi.jpg'
        self.num = 5

    
    def get_img(self, r):
        _request = requests.get(self.url, headers = {'Range':'bytes=%s-%s' % r})
        self.fd.seek(r[0])
        self.fd.write(_request.content)
        print 'success %s-%s' % r

    def get_range(self):
        r = requests.head(self.url)
        headers = r.headers
        image_size = int(headers['Content-Length'])
        # print [image_size]
        offset = image_size / self.num
        print image_size
        range_list = []
        for i in range(self.num):
            if i == self.num - 1:
                range_list.append((offset*i, ''))
            else:
                range_list.append((offset*i, offset*(i + 1)))
        return range_list


    def download(self):
        range_list = self.get_range()
        self.fd = open(self.name, 'w')
        for r in range_list:
            self.get_img(r)


if __name__ == "__main__":
    d = downloader()
    d.download()