昨天我们实现了Python的简易文件下载,但是那样速度太慢。
所以,今天我简单的实现了下Python下的多线程下载。
首先,让我们知道普通单线程的大概流程:
绘图1.jpg
然后,对于多线程下载,是这样的:
绘图2.jpg
在HTTP请求头中,有一个字段叫做Range。
这个字段用来将数据分割,每次请求可以请求不同部分的的数据,将这些数据同时下载就是多线程下载了。
那么,我们就需要两个东西:
一、HTTP头的构造
二、Python多线程编程
一、HTTP头的构造
一般的HTTP头是下图这样的:
QQ图片20151025173309.png
而我们要构造的带Range的头是这样的:
QQ截图20151025173510.png
这其中的区别就是在Range字段。
在Python里呢,我们可以用urllib.request
库中的两个函数来增加Range字段:
import urllib.request; #导入urllib.request库
url='http://www.example.com/1.txt';
req=urllib.request.Request(url); #得到该URL的请求HTTP头
req.add_header('Range','bytes=0-102400'); #在该请求头中,加入Range字段,并写出数据范围
u=urllib.request.urlopen(req); #用修改好的请求头打开链接
这样,我们就直到如何分片请求数据了。
二、Python简易多线程编程
下载线程的编写大概就像下面这样:
import threading;
class Download_Thread(threading.Thread): #用class类封装threading.Thread类型的Download_Thread对象
"""This is a Thread of Downloading"""
def __init__(self, ): #定义构造方法
super(Download_Thread, self).__init__();
self.url = url;
def run():
#以下写分片下载的代码
而开始一个新下载线程我们可以这样:
Download_Thread(#需要的参数).start();
这样就可以启动一个下载线程,在执行完start()函数内容之后,线程关闭(start()函数就是调用类中的run()函数)。
当然,有了这些还不够。你需要有一个函数能够来控制线程。
比如分配每个线程所要下载的数据范围;
得到每个线程返回的数据并将其插入文件中。
关于插入文件,我们可以这样:
f=open('1.txt','a+');
f.seek(#插入位置); #这里的插入位置指从文件起始的第n个字节处开始
f.write(data);
好了,现在我们可以写一个简易的多线程下载程序了:
import urllib.request,threading;
class Download_Thread(threading.Thread):
"""Download"""
def __init__(self, url,start_bit,end_bit,f): #构造方法,形参
super(Download_Thread, self).__init__();
self.url = url;
self.start_bit = start_bit;
self.end_bit=end_bit;
self.f=f;
def run():
req = urllib.request.Request(url); #得到请求头
req.add_header('Range','bytes='+str(self.start_bit)+'-'+str(self.end_bit));
u=urllib.request.urlopen(url); #上面是添加Range字段
self.data=[]; #下载开始
block=8192;
while True:
buf=u.read(block);
if(len(buf)==0):
break;
self.data.append(buf);
Insert(); #调用插入文件函数
def Insert():
self.f.seek(self.start_bit); #文件寻址到start_bit
i=0;
while(i
文章评论
博主 你的博客小人物怎么实现的