2009-06-10 7 views
8

Tengo una tarea para descargar Gbs de datos de un sitio web. Los datos están en forma de archivos .gz, cada archivo tiene un tamaño de 45 MB.wget Vs urlretrieve of python

La manera más fácil de obtener los archivos es usar "wget ​​-r -np -A url de archivos". Esto descargará los datos en un formato recursivo y reflejará el sitio web. La velocidad de descarga es muy alta 4mb/seg.

Pero, para jugar, también estaba usando python para construir mi urlparser.

La descarga a través de la recuperación url de Python es muy lenta, es posible 4 veces más lenta que wget. La tasa de descarga es de 500kb/seg. Uso HTMLParser para analizar las etiquetas href.

No estoy seguro de por qué sucede esto. ¿Hay alguna configuración para esto?

Gracias

+1

¿Ha intentado comparar el uso de la CPU y la salida de tcpdump? –

+0

¿Qué es tcpdump? ¿cómo conseguirlo? –

+1

¡Ignoraría las velocidades de transferencia (megabytes/MB y megabits/Mb son completamente diferentes!) Y compararía los dos usando los comandos 'time wget http: // example.com/file' y' time python urlretrieve_downloader.py' – dbr

Respuesta

1

Tal vez se puede wget y luego inspeccionar los datos en Python?

+0

lo siento, no puedo entender lo que quería decir ... ¿está diciendo que llame a wget desde el código python? –

+0

Podría hacerlo, o desde el caparazón, aprovechando la velocidad de descarga rápida ... luego procesar datos usando Python. –

0

No debería haber una diferencia realmente. Todo lo que hace urlretrieve es hacer una simple solicitud HTTP GET. ¿Has sacado tu código de procesamiento de datos y has hecho una comparación directa entre wget y pure python?

0

Por favor muéstranos el código. Estoy bastante seguro de que tiene que ser con el código y no con urlretrieve.

He trabajado con esto en el pasado y nunca he tenido ningún problema relacionado con la velocidad.

+0

Aquí está el código ... http: //cs.jhu.edu/~kapild/MyHtmlParser1.py El urlretrieve está en la segunda línea de la última –

1
import subprocess 

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

subproceso es su amigo :-) –

3

En cuanto al análisis de HTML, el más rápido/más fácil es probable que se obtiene es utilizando lxml En cuanto a la http mismos solicita: httplib2 es muy fácil de usar, y posiblemente podría acelerar las descargas, ya que soporta HTTP 1.1 keep-alive conexiones y compresión gzip. También hay pycURL que dice ser muy rápido (pero más difícil de usar), y está basado en curllib, pero nunca lo he usado.

También podría tratar de descargar diferentes archivos al mismo tiempo, pero también tenga en cuenta que tratar de optimizar sus tiempos de descarga demasiado puede no ser muy cortés con el sitio web en cuestión.

Lo siento por la falta de hipervínculos, pero por lo que me dice "lo siento, los nuevos usuarios sólo pueden enviar un máximo de un hipervínculo"

+0

Agregado algunos enlaces para ti, newb :) – Triptych

+0

No estoy seguro de si el problema es el análisis ... Su recuperación y almacenamiento del archivo que está causando el retraso ... –

3

velocidades de transferencia puede ser engañosa facilidad .. ¿Podrías tratar con el siguiente script, el cual simplemente descargue la misma URL con wget y urllib.urlretrieve; ejecútela varias veces en caso de que esté detrás de un proxy que almacena en caché la URL en el segundo intento.

Para archivos pequeños, wget tardará un poco más debido al tiempo de inicio del proceso externo, pero para archivos más grandes que deberían ser irrelevantes.

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 funciona para mí tan rápido como wget. prueba este código muestra el progreso en porcentaje igual que 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

Puede utilizar wget -k para participar enlaces relativos en todas las direcciones URL.

1

Dado que python sugiere utilizar urllib2 en lugar de urllib, realizo una prueba entre urllib2.urlopen y wget.

El resultado es que se tarda casi el mismo tiempo para que ambos descarguen el mismo archivo. A veces, urllib2 funciona aún mejor.

La ventaja de wget se encuentra en una barra de progreso dinámica para mostrar el porcentaje de finalización y la velocidad de descarga actual durante la transferencia.

El tamaño del archivo en mi prueba es 5MB. No he usado ningún módulo de caché en python y no sé cómo funciona wget al descargar archivos de gran tamaño.