python代码示例下载-Python实现多线程下载脚本的示例代码

0x01 分析

一个简单的多线程下载资源的Python脚本,主要实现部分包含两个类:

Download类:包含download()和get_complete_rate()两种方法。download()方法种首先用 urlopen() 方法打开远程资源并通过 Content-Length获取资源的大小,然后计算每个线程应该下载网络资源的大小及对应部分吗,最后依次创建并启动多个线程来下载网络资源的指定部分。

get_complete_rate()则是用来返回已下载的部分占全部资源大小的比例,用来回显进度。

ThreadDownload类:该线程类继承了threading.Thread类,包含了一个run()方法。

run()方法主要负责每个线程读取网络数据并写入本地。

0x02 代码# 文件名:ThreadDownload.py

import threading

from urllib.request import *

class Download:

def __init__(self, link, file_path, thread_num):

# 下载路径

self.link = link

# 保存位置

self.file_path = file_path

# 使用多少线程

self.thread_num = thread_num

# 初始化threads数组

self.threads = []

def download(self):

req = Request(url=self.link, method='GET')

req.add_header('Accept', '*/*')

req.add_header('Charset', 'UTF-8')

req.add_header('Connection', 'Keep-Alive')

f = urlopen(req)

# 获取要下载的文件的大小

self.file_size = int(dict(f.headers).get('Content-Length', 0))

f.close()

# 计算每个线程要下载的资源的大小

current_part_size = self.file_size // self.thread_num + 1

for i in range(self.thread_num):

# 计算每个线程下载的开始位置

start_pos = i * current_part_size

# 每个线程使用一个wb模式打开的文件进行下载

t = open(self.file_path, 'wb')

t.seek(start_pos, 0)

# 创建下载线程

td = ThreadDownload(self.link, start_pos, current_part_size, t)

self.threads.append(td)

td.start()

# 获下载的完成百分比

def get_complete_rate(self):

sum_size = 0

for i in range(self.thread_num):

sum_size += self.threads[i].length

return sum_size / self.file_size

class ThreadDownload(threading.Thread):

def __init__(self, link, start_pos, current_part_size, current_part):

super().__init__()

# 下载路径

self.link = link

# 当前线程的下载位置

self.start_pos = start_pos

# 定义当前线程负责下载的文件大小

self.current_part_size = current_part_size

# 当前文件需要下载的文件快

self.current_part = current_part

# 定义该线程已经下载的字节数

self.length = 0

def run(self):

req = Request(url = self.link, method='GET')

req.add_header('Accept', '*/*')

req.add_header('Charset', 'UTF-8')

req.add_header('Connection', 'Keep-Alive')

f = urlopen(req)

# 跳过self.start_pos个字节,表明该线程只负责下载自己负责的那部分内容

for i in range(self.start_pos):

f.read(1)

# 读取网络数据,并写入本地

while self.length < self.current_part_size:

data = f.read(1024)

if data is None or len(data) <= 0:

break

self.current_part.write(data)

# 累计该线程下载的总大小

self.length += len(data)

self.current_part.close()

f.close()#!/usr/bin/env python

# -*- coding: utf-8 -*-

# 文件名:thread_download-master.py

import sys

import time

from ThreadDownload import *

def show_process(dl):

while dl.get_complete_rate() < 1:

complete_rate = int(dl.get_complete_rate()*100)

print(' ' + '下载中···(已下载' + str(complete_rate) + '%)', end='', flush=True)

time.sleep(0.01)

def main():

try:

Link = input('[+]' + 'Link: ')

file_path = input('[+]' + 'File Path: ')

thread_number = input('[+]' + 'Thread Number: ')

thread_number = int(thread_number)

dl = Download(Link, file_path, thread_number)

dl.download()

print(' 开始下载!')

show_process(dl)

print(' ' + '下载中···(已下载' + '100%)', end='', flush=True)

print(' 下载完成!')

except Exception:

print('Parameter Setting Error')

sys.exit(1)

if __name__=='__main__':

main()

0x03 运行结果

下载歌曲《男孩》为例,下载到./Download/目录下并命名为男孩.mp3,设置5个线程:

下载成功:

到此这篇关于Python实现多线程下载脚本的示例代码的文章就介绍到这了,更多相关Python 多线程下载脚本内容请搜索ZaLou.Cn以前的文章或继续浏览下面的相关文章希望大家以后多多支持ZaLou.Cn!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值