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基础教程之简单入门说明(变量和控制语言使用方法)
Mar 25 Python
Python实现二叉堆
Feb 03 Python
python 简单的多线程链接实现代码
Aug 28 Python
Python网络编程详解
Oct 31 Python
CentOS7.3编译安装Python3.6.2的方法
Jan 22 Python
Python 字符串操作(string替换、删除、截取、复制、连接、比较、查找、包含、大小写转换、分割等)
Mar 19 Python
在python3.5中使用OpenCV的实例讲解
Apr 02 Python
Python 中的range(),以及列表切片方法
Jul 02 Python
Python 中Django安装和使用教程详解
Jul 03 Python
python函数装饰器之带参数的函数和带参数的装饰器用法示例
Nov 06 Python
python脚本实现mp4中的音频提取并保存在原目录
Feb 27 Python
2021年pycharm的最新安装教程及基本使用图文详解
Apr 03 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
PHPStorm 2020.1 调试 Nodejs的多种方法详解
2020/09/17 NodeJs
jquery focus(fn),blur(fn)方法实例代码
2011/12/16 Javascript
jQuery获取Radio,CheckBox选择的Value值(示例代码)
2013/12/12 Javascript
js弹出div并显示遮罩层
2014/02/12 Javascript
jquery制作图片时钟特效
2020/03/30 Javascript
使用JavaScript解决网页图片拉伸问题(推荐)
2016/11/25 Javascript
nodejs前端自动化构建环境的搭建
2017/07/26 NodeJs
Vue2.0基于vue-cli+webpack Vuex的用法(实例讲解)
2017/09/15 Javascript
BootStrap Validator 根据条件在JS中添加或移除校验操作
2017/10/12 Javascript
webpack+vuex+axios 跨域请求数据的示例代码
2018/03/06 Javascript
vue.js使用watch监听路由变化的方法
2018/07/08 Javascript
微信小程序实现自定义加载图标功能
2018/07/19 Javascript
使用Vue 实现滑动验证码功能
2019/06/27 Javascript
解决Vue在Tomcat8下部署页面不加载的问题
2019/11/12 Javascript
python django集成cas验证系统
2014/07/14 Python
Python专用方法与迭代机制实例分析
2014/09/15 Python
python使用fileinput模块实现逐行读取文件的方法
2015/04/29 Python
Python管理Windows服务小脚本
2018/03/12 Python
python中dir()与__dict__属性的区别浅析
2018/12/10 Python
python操作小程序云数据库实现简单的增删改查功能
2019/06/06 Python
用Python+OpenCV对比图像质量的几种方法
2019/07/15 Python
Python之数据序列化(json、pickle、shelve)详解
2019/08/30 Python
python rsa实现数据加密和解密、签名加密和验签功能
2019/09/18 Python
在 Pycharm 安装使用black的方法详解
2020/04/02 Python
Softmax函数原理及Python实现过程解析
2020/05/22 Python
html5声频audio和视频video等新特性详细说明
2012/12/26 HTML / CSS
详解canvas多边形(蜘蛛图)的画法示例
2018/01/29 HTML / CSS
Otel.com:折扣酒店预订
2017/08/24 全球购物
全球度假村:Club Med
2017/11/27 全球购物
美国专业汽车音响和移动电子产品零售商:Car Toys
2019/05/13 全球购物
J2EE相关知识面试题
2013/08/26 面试题
网吧消防安全责任书
2014/07/29 职场文书
教务处干事工作总结
2015/08/14 职场文书
mysql数据库入门第一步之创建表
2021/05/14 MySQL
健身房被搭讪?用python写了个小米计时器助人为乐
2021/06/08 Python
Python中re模块的元字符使用小结
2022/04/07 Python