Implémentation Python d'un exemple de téléchargeur HTTP multithread

高洛峰
Libérer: 2017-02-13 13:40:01
original
1514 Les gens l'ont consulté

Cet article présentera l'utilisation de Python pour écrire un téléchargeur HTTP multithread et générer un fichier exécutable .exe.

Environnement : Windows/Linux Python2.7.x

Monothread

Introduisez d'abord le monothread avant d'introduire le multi-threading. L'idée d'écrire un seul fil de discussion est la suivante :

1. Analyser l'URL

2. >
3. Construisez un package de requête http ;


4. Téléchargez le fichier.

Ce qui suit est expliqué par le code.

Analyser l'URLAnalysé par l'URL d'entrée de l'utilisateur. Si le chemin analysé est vide, la valeur attribuée est « / » ; si le numéro de port est vide, la valeur attribuée est « 80 » ; le nom du fichier téléchargé peut être modifié selon les souhaits de l'utilisateur (entrez « y »). pour indiquer un changement, entrez autre pour indiquer qu'aucune modification n'est requise).

Plusieurs fonctions d'analyse sont répertoriées ci-dessous :

#解析host和path
def analyHostAndPath(totalUrl):
  protocol,s1 = urllib.splittype(totalUrl)
  host, path = urllib.splithost(s1)
  if path == '':
    path = '/'
  return host, path

#解析port
def analysisPort(host):
  host, port = urllib.splitport(host)
  if port is None:
    return 80
  return port

#解析filename
def analysisFilename(path):
  filename = path.split('/')[-1]
  if '.' not in filename:
    return None
  return filename
Copier après la connexion

Se connecter au serveur Web

Utilisez le module socket pour vous connecter au serveur Web en fonction de l'hôte et du port obtenus en analysant l'URL. Le code est le suivant :

import socket
from analysisUrl import port,host

ip = socket.gethostbyname(host)
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect((ip, port))

print "success connected webServer!!"
Copier après la connexion

<. 🎜>Construisez un package de requête HTTP

Construisez un package de requête HTTP basé sur le chemin, l'hôte et le port obtenus en analysant l'URL.

from analysisUrl import path, host, port

packet = &#39;GET &#39; + path + &#39; HTTP/1.1\r\nHost: &#39; + host + &#39;\r\n\r\n&#39; 
Copier après la connexion

Téléchargez le fichier

Envoyez le fichier au serveur et récupérez la réponse en fonction du construit Package de requête http "Content-Length" dans l'en-tête du message.

def getLength(self):
    s.send(packet)
    print "send success!"
    buf = s.recv(1024)
    print buf
    p = re.compile(r&#39;Content-Length: (\d*)&#39;)
    length = int(p.findall(buf)[0])
    return length, buf
Copier après la connexion
Téléchargez le fichier et calculez le temps de téléchargement.

def download(self):
    file = open(self.filename,&#39;wb&#39;)
    length,buf = self.getLength()
    packetIndex = buf.index(&#39;\r\n\r\n&#39;)
    buf = buf[packetIndex+4:]
    file.write(buf)
    sum = len(buf)
    while 1:
      buf = s.recv(1024)
      file.write(buf)
      sum = sum + len(buf)
      if sum >= length:
        break
    print "Success!!"

if __name__ == "__main__":
  start = time.time()
  down = downloader()
  down.download()
  end = time.time()
  print "The time spent on this program is %f s"%(end - start)
Copier après la connexion

Multi-thread

Capturez le champ "Content-Length" dans l'en-tête du message de réponse, Combiné au nombre de threads, le téléchargement segmenté est verrouillé. Différent du code monothread, tout le code est intégré ici dans un seul fichier et davantage de modules intégrés Python sont utilisés dans le code.

Obtenez "Content-Length" :

def getLength(self):
    opener = urllib2.build_opener()
    req = opener.open(self.url)
    meta = req.info()
    length = int(meta.getheaders("Content-Length")[0])
    return length
Copier après la connexion
Selon la longueur obtenue, combinez le nombre de fils pour diviser la plage :

def get_range(self):
    ranges = []
    length = self.getLength()
    offset = int(int(length) / self.threadNum)
    for i in range(self.threadNum):
      if i == (self.threadNum - 1):
        ranges.append((i*offset,&#39;&#39;))
      else:
        ranges.append((i*offset,(i+1)*offset))
    return ranges
Copier après la connexion
Implémentez le téléchargement multithread Lorsque vous écrivez du contenu dans le fichier, verrouillez le fil et utilisez avec lock au lieu de lock.acquire(). .lock. release(); Utilisez file.seek() pour définir l'adresse de décalage du fichier afin de garantir l'exactitude de l'écriture des fichiers.

def downloadThread(self,start,end):
    req = urllib2.Request(self.url)
    req.headers[&#39;Range&#39;] = &#39;bytes=%s-%s&#39; % (start, end)
    f = urllib2.urlopen(req)
    offset = start
    buffer = 1024
    while 1:
      block = f.read(buffer)
      if not block:
        break
      with lock:
        self.file.seek(offset)
        self.file.write(block)
        offset = offset + len(block)

  def download(self):
    filename = self.getFilename()
    self.file = open(filename, &#39;wb&#39;)
    thread_list = []
    n = 1
    for ran in self.get_range():
      start, end = ran
      print &#39;starting:%d thread &#39;% n
      n += 1
      thread = threading.Thread(target=self.downloadThread,args=(start,end))
      thread.start()
      thread_list.append(thread)

    for i in thread_list:
      i.join()
    print &#39;Download %s Success!&#39;%(self.file)
    self.file.close()
Copier après la connexion
Résultat d'exécution :

Implémentation Python dun exemple de téléchargeur HTTP multithreadConvertir le fichier (*.py) après écrire un outil pour les fichiers exécutables (*.exe)

, comment permettre aux personnes qui n'ont pas installé Python d'utiliser cet outil ? Cela nécessite de convertir le fichier .py en fichier .exe.

Le module py2exe de Python est utilisé ici. C'est la première fois que je l'utilise, je vais donc le présenter :

py2exe est un fichier exécutable qui convertit un script Python en un exécutable indépendant. fichier sur l'outil Windows (*.exe), afin que vous puissiez exécuter ce programme exécutable sous Windows sans installer Python.

Ensuite, créez le fichier mysetup.py dans le même répertoire que multiThreadDownload.py et écrivez :

from distutils.core import setup
import py2exe

setup(console=["multiThreadDownload.py"])
Copier après la connexion
Ensuite, exécutez la commande : Python mysetup.py py2exe

génère le dossier dist, le fichier multiTjhreadDownload.exe se trouve dedans, cliquez pour exécuter :

Implémentation Python dun exemple de téléchargeur HTTP multithread

Adresse de téléchargement de la démo : HttpFileDownload_jb51.rarImplémentation Python dun exemple de téléchargeur HTTP multithread

Ce qui précède est l'intégralité du contenu de cet article. J'espère qu'il sera utile à l'apprentissage de chacun, et j'espère également que tout le monde soutiendra le. Site Web chinois PHP.

Pour plus d'articles liés à l'implémentation Python d'exemples de téléchargeurs HTTP multithread, veuillez faire attention au site Web PHP chinois !

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal