Maison  >  Article  >  développement back-end  >  Implémentation Python d'un exemple de téléchargeur HTTP multithread

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

高洛峰
高洛峰original
2017-02-13 13:40:011509parcourir

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

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!!"

<.>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; 

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
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)

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
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
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()
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"])
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 !

Déclaration:
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