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
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 = 'GET ' + path + ' HTTP/1.1\r\nHost: ' + host + '\r\n\r\n'
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'Content-Length: (\d*)') length = int(p.findall(buf)[0]) return length, buf
def download(self): file = open(self.filename,'wb') length,buf = self.getLength() packetIndex = buf.index('\r\n\r\n') 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
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,'')) else: ranges.append((i*offset,(i+1)*offset)) return ranges
def downloadThread(self,start,end): req = urllib2.Request(self.url) req.headers['Range'] = 'bytes=%s-%s' % (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, 'wb') thread_list = [] n = 1 for ran in self.get_range(): start, end = ran print 'starting:%d thread '% 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 'Download %s Success!'%(self.file) self.file.close()
Convertir 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"])
Adresse de téléchargement de la démo : HttpFileDownload_jb51.rar
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.