web-dev-qa-db-fra.com

Diffusez de gros fichiers binaires avec urllib2 dans un fichier

J'utilise le code suivant pour diffuser des fichiers volumineux d'Internet dans un fichier local:

fp = open(file, 'wb')
req = urllib2.urlopen(url)
for line in req:
    fp.write(line)
fp.close()

Cela fonctionne mais il se télécharge assez lentement. Y at-il un moyen plus rapide? (Les fichiers sont volumineux, donc je ne veux pas les garder en mémoire.)

53
hoju

Aucune raison de travailler ligne par ligne (petits morceaux ET nécessite Python pour trouver la fin de la ligne pour vous! -), il suffit de la fragmenter en plus gros morceaux, par exemple:

# from urllib2 import urlopen # Python 2
from urllib.request import urlopen # Python 3

response = urlopen(url)
CHUNK = 16 * 1024
with open(file, 'wb') as f:
    while True:
        chunk = response.read(CHUNK)
        if not chunk:
            break
        f.write(chunk)

Expérimentez un peu avec différentes tailles de CHUNK pour trouver le "sweet spot" pour vos besoins.

105
Alex Martelli

Vous pouvez également utiliser shutil :

import shutil
try:
    from urllib.request import urlopen # Python 3
except ImportError:
    from urllib2 import urlopen # Python 2

def get_large_file(url, file, length=16*1024):
    req = urlopen(url)
    with open(file, 'wb') as fp:
        shutil.copyfileobj(req, fp, length)
64
Tiago

J'avais l'habitude d'utiliser le module mechanize et sa méthode Browser.retrieve (). Dans le passé, cela prenait 100% de CPU et téléchargeait les choses très lentement, mais certaines versions récentes ont corrigé ce bogue et fonctionnent très rapidement.

Exemple:

import mechanize
browser = mechanize.Browser()
browser.retrieve('http://www.kernel.org/pub/linux/kernel/v2.6/testing/linux-2.6.32-rc1.tar.bz2', 'Downloads/my-new-kernel.tar.bz2')

Mechanize est basé sur urllib2, donc urllib2 peut également avoir une méthode similaire ... mais je n'en trouve plus maintenant.

6
liori

Vous pouvez utiliser urllib.retrieve () pour télécharger des fichiers:

Exemple:

try:
    from urllib import urlretrieve # Python 2

except ImportError:
    from urllib.request import urlretrieve # Python 3

url = "http://www.examplesite.com/myfile"
urlretrieve(url,"./local_file")
4
Aravindh