1. 程式人生 > 程式設計 >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,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,'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,thread_number)
    dl.download()
    print('\n開始下載!')
    show_process(dl)
    print('\r' + '下載中···(已下載' + '100%)',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 多執行緒下載指令碼內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!