Voici un script Python qui enregistre url donnée à un fichier et utilise plusieurs threads pour le télécharger:
#!/usr/bin/env python
import sys
from functools import partial
from itertools import count, izip
from multiprocessing.dummy import Pool # use threads
from urllib2 import HTTPError, Request, urlopen
def download_chunk(url, byterange):
req = Request(url, headers=dict(Range='bytes=%d-%d' % byterange))
try:
return urlopen(req).read()
except HTTPError as e:
return b'' if e.code == 416 else None # treat range error as EOF
except EnvironmentError:
return None
def main():
url, filename = sys.argv[1:]
pool = Pool(4) # define number of concurrent connections
chunksize = 1 << 16
ranges = izip(count(0, chunksize), count(chunksize - 1, chunksize))
with open(filename, 'wb') as file:
for s in pool.imap(partial(download_part, url), ranges):
if not s:
break # error or EOF
file.write(s)
if len(s) != chunksize:
break # EOF (servers with no Range support end up here)
if __name__ == "__main__":
main()
La fin du fichier est détecté si un serveur retourne corps vide, ou 416 code http, ou si la taille de la réponse n'est pas chunksize
exactement.
Il prend en charge les serveurs qui ne comprennent pas Range
en-tête (tout est téléchargé dans une seule demande dans ce cas, pour soutenir les fichiers volumineux, changer download_chunk()
pour enregistrer dans un fichier temporaire et retourner le nom de fichier à lire dans le fil principal au lieu du contenu du fichier lui-même).
Il permet de modifier indépendamment le nombre de connexions simultanées (taille du pool) et le nombre d'octets requis dans une seule requête http.
Pour utiliser plusieurs processus au lieu de fils, changer l'importation:
from multiprocessing.pool import Pool # use processes (other code unchanged)
Si vous avez vraiment besoin de télécharger 1 fichier, puis juste aller à un terminal sous Linux (si vous utilisez linux) et exécutez 'aria2c -x 16 -s 20'. J'aime ma solution parce que chaque fois que j'ai plusieurs gros fichiers (ou même seulement un gros fichier) que j'ai besoin de télécharger, je les jette dans le répertoire 'MY_HTTP_LOC', puis j'exécute mon script. –
synaptik