2011-08-03 15 views
6

Estoy descargando archivos de un servidor FTP escamoso que a menudo se agota durante la transferencia de archivos y me preguntaba si había una forma de volver a conectar y reanudar la descarga. Estoy usando el ftplib de Python. Aquí está el código que estoy usando:Reanudar la descarga de FTP después del tiempo de espera

#! /usr/bin/python 

import ftplib 
import os 
import socket 
import sys 

#--------------------------------# 
# Define parameters for ftp site # 
#--------------------------------# 
site   = 'a.really.unstable.server' 
user   = 'anonymous' 
password  = '[email protected]' 
root_ftp_dir = '/directory1/' 
root_local_dir = '/directory2/' 

#--------------------------------------------------------------- 
# Tuple of order numbers to download. Each web request generates 
# an order numbers 
#--------------------------------------------------------------- 
order_num = ('1','2','3','4') 

#----------------------------------------------------------------# 
# Loop through each order. Connect to server on each loop. There # 
# might be a time out for the connection therefore reconnect for # 
# every new ordernumber           # 
#----------------------------------------------------------------# 
# First change local directory 
os.chdir(root_local_dir) 

# Begin loop through 
for order in order_num: 

    print 'Begin Proccessing order number %s' %order 

    # Connect to FTP site 
    try: 
     ftp = ftplib.FTP(host=site, timeout=1200) 
    except (socket.error, socket.gaierror), e: 
     print 'ERROR: Unable to reach "%s"' %site 
     sys.exit() 

    # Login 
    try: 
     ftp.login(user,password) 
    except ftplib.error_perm: 
     print 'ERROR: Unable to login' 
     ftp.quit() 
     sys.exit() 

    # Change remote directory to location of order 
    try: 
     ftp.cwd(root_ftp_dir+order) 
    except ftplib.error_perm: 
     print 'Unable to CD to "%s"' %(root_ftp_dir+order) 
     sys.exit() 

    # Get a list of files 
    try: 
     filelist = ftp.nlst() 
    except ftplib.error_perm: 
     print 'Unable to get file list from "%s"' %order 
     sys.exit() 

    #---------------------------------# 
    # Loop through files and download # 
    #---------------------------------# 
    for each_file in filelist: 

     file_local = open(each_file,'wb') 

     try: 
      ftp.retrbinary('RETR %s' %each_file, file_local.write) 
      file_local.close() 
     except ftplib.error_perm: 
      print 'ERROR: cannot read file "%s"' %each_file 
      os.unlink(each_file) 

    ftp.quit() 

    print 'Finished Proccessing order number %s' %order 

sys.exit() 

El error que me sale: socket.error: [Errno 110] conexión excedida en

Cualquier ayuda es muy apreciada.

+0

Definitivamente echa un vistazo a http://ftputil.sschwarzer.net/trac, facilitará cualquier tarea relacionada con ftp. – agf

Respuesta

3

reanudar una descarga a través de FTP usando sólo las instalaciones estándar (véase RFC959) requiere el uso del modo de transmisión de bloque (sección 3.4.2), que se puede configurar mediante el comando MODE B. Aunque esta característica es técnicamente necesaria para la conformidad con la especificación, no estoy seguro de que todo el software del servidor FTP la implemente.

En el modo de transmisión de bloque, a diferencia del modo de transmisión de flujo, el servidor envía el archivo en fragmentos, cada uno de los cuales tiene un marcador. Este marcador puede volver a enviarse al servidor para reiniciar una transferencia fallida (sección 3.5).

La especificación dice:

[...] a restart procedure is provided to protect users from gross system failures (including failures of a host, an FTP-process, or the underlying network).

Sin embargo, yo sepa, la especificación no define un tiempo de vida requerido para marcadores. Sólo se dice lo siguiente:

The marker information has meaning only to the sender, but must consist of printable characters in the default or negotiated language of the control connection (ASCII or EBCDIC). The marker could represent a bit-count, a record-count, or any other information by which a system may identify a data checkpoint. The receiver of data, if it implements the restart procedure, would then mark the corresponding position of this marker in the receiving system, and return this information to the user.

Debe ser seguro asumir que los servidores de aplicación de esta función será proporcionar marcadores que son válidas entre las sesiones de FTP, pero su experiencia puede variar.

0

Para hacer esto, debería mantener la descarga interrumpida, luego descubrir qué partes del archivo falta, descargar esas partes y luego conectarlas entre sí. No estoy seguro de cómo hacer esto, pero hay un administrador de descargas para Firefox y Chrome llamado DownThemAll que hace esto. Aunque el código no está escrito en python (creo que es JavaScript), podrías mirar el código y ver cómo lo hace.

DownThemll - http://www.downthemall.net/

+0

DownThemAll está escrito en JavaScript y XUL (Lenguaje de interfaz de usuario XML). Fuente- http://en.wikipedia.org/wiki/DownThemAll! y https://github.com/nmaier/DownThemAll – Neil

Cuestiones relacionadas