2009-06-10 9 views
8

J'ai une tâche pour télécharger des Gbs de données à partir d'un site Web. Les données sont sous la forme de fichiers .gz, chaque fichier ayant une taille de 45mb.wget Vs urlretrieve de python

Le moyen le plus simple d'obtenir les fichiers est d'utiliser "wget ​​-r -np -A files url". Cela va télécharger les données dans un format récursif et reflète le site Web. Le taux de téléchargement est très élevé 4mb/sec. Mais, juste pour jouer, j'utilisais aussi python pour construire mon urlparser.

Le téléchargement via urlretrieve de Python est damm lent, possible 4 fois plus lent que wget. Le taux de téléchargement est 500kb/sec. J'utilise HTMLParser pour analyser les tags href.

Je ne sais pas pourquoi cela se produit. Y a-t-il des paramètres pour cela?

Merci

+1

Avez-vous essayé de comparer l'utilisation du processeur et la sortie de tcpdump? –

+0

qu'est-ce que tcpdump? Comment l'obtenir? –

+1

Je voudrais ignorer les vitesses de transfert (mégaoctets/Mo et mégabits/Mb sont complètement différents!) Et de comparer les deux en utilisant les commandes «temps wget http: // example.com/fichier» et «temps python urlretrieve_downloader.py» – dbr

Répondre

1

Peut-être que vous pouvez wget, puis vérifier les données en Python?

+0

désolé, je ne peux pas comprendre ce que vous vouliez dire .. dites-vous d'appeler wget de code python? –

+0

Vous pouvez faire, ou à partir du shell, en profitant de la vitesse de téléchargement rapide ... puis traiter les données en utilisant Python. –

0

Il ne devrait pas vraiment y avoir de différence. Tout ce que urlretrieve fait est une simple requête HTTP GET. Avez-vous sorti votre code de traitement de données et fait une comparaison directe entre wget et python pur?

0

Veuillez nous montrer le code. Je suis assez sûr que cela doit être avec le code et non sur urlretrieve. J'ai déjà travaillé avec cela par le passé et je n'ai jamais eu de problèmes liés à la vitesse.

+0

Voici le code ... http: //cs.jhu.edu/~kapild/MyHtmlParser1.py Le urlretrieve est dans la dernière ligne –

1
import subprocess 

myurl = 'http://some_server/data/' 
subprocess.call(["wget", "-r", "-np", "-A", "files", myurl]) 
+0

subprocess est votre ami :-) –

3

En ce qui concerne l'analyse syntaxique html, le plus rapide/vous aurez probablement plus facile obtenez est utilisé lxml Quant au http se demande: httplib2 est très facile à utiliser, et pourrait accélérer les téléchargements, car il prend en charge http 1.1 keep-alive connexions et compression gzip. Il y a également pycURL qui prétend être très rapide (mais plus difficile à utiliser), et est construit sur curllib, mais je n'ai jamais utilisé ça.

Vous pouvez également essayer de télécharger des fichiers différents simultanément, mais gardez également à l'esprit qu'essayer d'optimiser vos temps de téléchargement peut ne pas être très poli envers le site en question.

Désolé pour le manque de liens hypertextes, mais SO me dit « désolé, les nouveaux utilisateurs ne peuvent afficher un maximum d'un lien hypertexte »

+0

Ajouté quelques liens pour vous, newb :) – Triptych

+0

Je ne suis pas sûr si l'analyse est le problème ... Son fichier de récupération et de stockage qui provoque le retard ... –

3

Les vitesses de transfert peuvent être facilement induire en erreur .. Pouvez-vous essayer avec le script suivant, qui Il suffit de télécharger la même URL à la fois avec wget et urllib.urlretrieve - exécutez-le plusieurs fois, vous êtes derrière un proxy qui met en cache l'URL lors de la deuxième tentative.

Pour les petits fichiers, wget prendra un peu plus de temps en raison du temps de démarrage du processus externe, mais pour les fichiers plus volumineux qui ne devraient plus être pertinents.

from time import time 
import urllib 
import subprocess 

target = "http://example.com" # change this to a more useful URL 

wget_start = time() 

proc = subprocess.Popen(["wget", target]) 
proc.communicate() 

wget_end = time() 


url_start = time() 
urllib.urlretrieve(target) 
url_end = time() 

print "wget -> %s" % (wget_end - wget_start) 
print "urllib.urlretrieve -> %s" % (url_end - url_start) 
8

urllib fonctionne pour moi aussi vite que wget. essayez ce code. il montre la progression en pourcentage tout comme wget.

import sys, urllib 
def reporthook(a,b,c): 
    # ',' at the end of the line is important! 
    print "% 3.1f%% of %d bytes\r" % (min(100, float(a * b)/c * 100), c), 
    #you can also use sys.stdout.write 
    #sys.stdout.write("\r% 3.1f%% of %d bytes" 
    #     % (min(100, float(a * b)/c * 100), c) 
    sys.stdout.flush() 
for url in sys.argv[1:]: 
    i = url.rfind('/') 
    file = url[i+1:] 
    print url, "->", file 
    urllib.urlretrieve(url, file, reporthook) 
0

Vous pouvez utiliser wget -k pour engager des liens relatifs à tous les urls.

1

Depuis python suggère d'utiliser urllib2 au lieu de urllib, je prends un test entre urllib2.urlopen et wget.

Le résultat est, il faut presque le même temps pour les deux de télécharger le même fichier. Parfois, urllib2 fonctionne encore mieux. L'avantage de wget réside dans une barre de progression dynamique pour afficher le pourcentage fini et la vitesse de téléchargement en cours lors du transfert.

La taille du fichier dans mon test est 5MB. Je n'ai utilisé aucun module de cache en python et je ne suis pas au courant de la façon dont wget fonctionne lorsque vous téléchargez un fichier de grande taille.