2011-08-03 8 views
6

Je télécharge des fichiers à partir d'un serveur FTP flaky qui expire souvent pendant le transfert de fichiers et je me demandais s'il y avait un moyen de se reconnecter et de reprendre le téléchargement. J'utilise ftplib de python. Voici le code que j'utilise:Reprendre le téléchargement FTP après le délai

#! /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() 

L'erreur que je reçois: socket.error: [Errno 110] Délai de connexion dépassé

Toute aide est grandement appréciée.

+0

Jetez un coup d'œil sur http://ftputil.sschwarzer.net/trac, cela facilitera toute tâche liée au ftp. – agf

Répondre

3

Reprise d'un téléchargement par FTP en utilisant uniquement des équipements standard (voir RFC959) nécessite l'utilisation du mode de transmission de bloc (section 3.4.2), qui peut être réglé en utilisant la commande MODE B. Bien que cette fonctionnalité soit techniquement requise pour la conformité à la spécification, je ne suis pas sûr que tous les logiciels serveur FTP l'implémente. En mode de transmission par blocs, par opposition au mode de transmission par flux, le serveur envoie le fichier par morceaux, chacun d'entre eux ayant un marqueur. Ce marqueur peut être soumis à nouveau au serveur pour redémarrer un transfert échoué (section 3.5).

La spécification dit:

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

Cependant, autant que je sache, la spécification ne définit pas une durée de vie requise pour les marqueurs. Il dit que les suivantes:

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.

Il doit être sûr de supposer que les serveurs de mise en œuvre de cette fonction fournira des marqueurs valides entre les sessions FTP, mais votre kilométrage peut varier.

0

Pour ce faire, vous devez garder le téléchargement interrompu, puis déterminer quelles parties du fichier que vous manquez, téléchargez les parties et les relier entre eux. Je ne suis pas sûr de savoir comment faire cela, mais il y a un gestionnaire de téléchargement pour Firefox et Chrome appelé DownThemAll qui le fait. Bien que le code ne soit pas écrit en python (je pense que c'est du JavaScript), vous pouvez regarder le code et voir comment il le fait.

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

+0

DownThemAll est écrit en JavaScript et XUL (XML User Interface Language). Source- http://en.wikipedia.org/wiki/DownThemAll! et https://github.com/nmaier/DownThemAll – Neil

Questions connexes