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


Posted in Python onApril 03, 2020

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('\r' + '下载中···(已下载' + 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('\n开始下载!')
    show_process(dl)
    print('\r' + '下载中···(已下载' + '100%)', end='', flush=True)
    print('\n下载完成!')
  except Exception:
      print('Parameter Setting Error')
      sys.exit(1)

if __name__=='__main__':
    main()

0x03 运行结果

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

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

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

下载成功:

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

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

Python 相关文章推荐
python 控制语句
Nov 03 Python
使用Python的Treq on Twisted来进行HTTP压力测试
Apr 16 Python
windows下添加Python环境变量的方法汇总
May 14 Python
Python分析彩票记录并预测中奖号码过程详解
Jul 09 Python
python多线程共享变量的使用和效率方法
Jul 16 Python
python使用百度文字识别功能方法详解
Jul 23 Python
pytorch 获取tensor维度信息示例
Jan 03 Python
tensorflow 变长序列存储实例
Jan 20 Python
浅谈matplotlib中FigureCanvasXAgg的用法
Jun 16 Python
keras训练浅层卷积网络并保存和加载模型实例
Jul 02 Python
基于python模拟bfs和dfs代码实例
Nov 19 Python
Python基础之常用库常用方法整理
Apr 30 Python
python实现将两个文件夹合并至另一个文件夹(制作数据集)
Apr 03 #Python
pycharm安装及如何导入numpy
Apr 03 #Python
解决pyPdf和pyPdf2在合并pdf时出现异常的问题
Apr 03 #Python
Python利用PyPDF2库获取PDF文件总页码实例
Apr 03 #Python
Numpy 理解ndarray对象的示例代码
Apr 03 #Python
python计算Content-MD5并获取文件的Content-MD5值方式
Apr 03 #Python
Django自定义列表 models字段显示方式
Apr 03 #Python
You might like
安装APACHE
2007/01/15 PHP
关于php支持分块与断点续传文件下载功能代码
2014/05/09 PHP
php cookie中点号(句号)自动转为下划线问题
2014/10/21 PHP
JQuery实现自定义对话框的代码
2008/06/15 Javascript
cookie在javascript中的使用技巧以及隐私在服务器端的设置
2012/12/03 Javascript
jQuery插件实现屏蔽单个元素使用户无法点击
2013/04/12 Javascript
Easyui的组合框的取值与赋值
2016/10/28 Javascript
JavaScript仿微博输入框效果(案例分析)
2016/12/06 Javascript
基于react框架使用的一些细节要点的思考
2017/05/31 Javascript
js实现复制功能(多种方法集合)
2018/01/06 Javascript
微信公众号H5支付接口调用方法
2019/01/10 Javascript
WebGL学习教程之Three.js学习笔记(第一篇)
2019/04/25 Javascript
vue-router的hooks用法详解
2020/06/08 Javascript
JavaScript中数组去重的5种方法
2020/07/04 Javascript
在js文件中引入(调用)另一个js文件的三种方法
2020/09/11 Javascript
TypeScript魔法堂之枚举的超实用手册
2020/10/29 Javascript
nodejs中的异步编程知识点详解
2021/01/17 NodeJs
Python生成随机数的方法
2014/01/14 Python
python绘制圆柱体的方法
2018/07/02 Python
在pycharm 中添加运行参数的操作方法
2019/01/19 Python
在Python运行时动态查看进程内部信息的方法
2019/02/22 Python
如何使用python把ppt转换成pdf
2019/06/29 Python
python写日志文件操作类与应用示例
2019/07/01 Python
Python pip替换为阿里源的方法步骤
2019/07/02 Python
pandas删除行删除列增加行增加列的实现
2019/07/06 Python
Python 类方法和实例方法(@classmethod),静态方法(@staticmethod)原理与用法分析
2019/09/20 Python
斐乐美国官方网站:FILA美国
2019/03/01 全球购物
Aurora London官网:奢华、负担得起的皮革手袋
2020/08/01 全球购物
财政局长自荐信范文
2013/12/22 职场文书
俄语专业职业生涯规划
2014/02/26 职场文书
舞蹈兴趣小组活动总结
2014/07/07 职场文书
教育局党的群众路线教育实践活动整改方案
2014/09/20 职场文书
css实现文章分割线样式的多种方法总结
2021/04/21 HTML / CSS
java中重写父类方法加不加@Override详解
2021/06/21 Java/Android
微信小程序APP页面的之间的相互传递参数以及自定义组件
2022/04/19 Javascript
HTML静态页面获取url参数和UserAgent的实现
2022/08/05 HTML / CSS