Python FTP obtiene el archivo más reciente por fecha

Estoy usando ftplib para conectarme a un sitio ftp. Quiero obtener el archivo cargado más recientemente y descargarlo. Puedo conectarme al servidor ftp y listar los archivos, también los puse en una lista y datefield el datefield . ¿Existe alguna función / módulo que pueda obtener la fecha reciente y generar la línea completa de la lista?

 #!/usr/bin/env python import ftplib import os import socket import sys HOST = 'test' def main(): try: f = ftplib.FTP(HOST) except (socket.error, socket.gaierror), e: print 'cannot reach to %s' % HOST return print "Connect to ftp server" try: f.login('anonymous','al@ge.com') except ftplib.error_perm: print 'cannot login anonymously' f.quit() return print "logged on to the ftp server" data = [] f.dir(data.append) for line in data: datestr = ' '.join(line.split()[0:2]) orig-date = time.strptime(datestr, '%d-%m-%y %H:%M%p') f.quit() return if __name__ == '__main__': main() 

RESUELTO:

 data = [] f.dir(data.append) datelist = [] filelist = [] for line in data: col = line.split() datestr = ' '.join(line.split()[0:2]) date = time.strptime(datestr, '%m-%d-%y %H:%M%p') datelist.append(date) filelist.append(col[3]) combo = zip(datelist,filelist) who = dict(combo) for key in sorted(who.iterkeys(), reverse=True): print "%s: %s" % (key,who[key]) filename = who[key] print "file to download is %s" % filename try: f.retrbinary('RETR %s' % filename, open(filename, 'wb').write) except ftplib.err_perm: print "Error: cannot read file %s" % filename os.unlink(filename) else: print "***Downloaded*** %s " % filename return f.quit() return 

Un problema, ¿es posible recuperar el primer elemento del diccionario? Lo que hice aquí es que el bucle for se ejecuta solo una vez y, por lo tanto, sale del primer valor ordenado que está bien, pero no creo que sea una buena práctica hacerlo de esta manera …

Si tiene todas las fechas en time.struct_time ( strptime le dará esto) en una lista, entonces todo lo que tiene que hacer es sort la lista.

Aquí hay un ejemplo:

 #!/usr/bin/python import time dates = [ "Jan 16 18:35 2012", "Aug 16 21:14 2012", "Dec 05 22:27 2012", "Jan 22 19:42 2012", "Jan 24 00:49 2012", "Dec 15 22:41 2012", "Dec 13 01:41 2012", "Dec 24 01:23 2012", "Jan 21 00:35 2012", "Jan 16 18:35 2012", ] def main(): datelist = [] for date in dates: date = time.strptime(date, '%b %d %H:%M %Y') datelist.append(date) print datelist datelist.sort() print datelist if __name__ == '__main__': main() 

¿Por qué no usas la siguiente opción de directorio?

 ftp.dir('-t',data.append) 

Con esta opción, la lista de archivos es ordenada desde el más reciente al más antiguo. Luego simplemente recupere el primer archivo de la lista para descargarlo.

Para aquellos que buscan una solución completa para encontrar el último archivo en una carpeta:

MLSD

Si su servidor FTP admite el comando MLSD , una solución es fácil:

 entries = list(ftp.mlsd()) entries.sort(key = lambda entry: entry[1]['modify'], reverse = True) latest_name = entries[0][0] print(latest_name) 

LISTA

Si necesita confiar en un comando LIST obsoleto, debe analizar un listado propietario que devuelve.

El listado común de * nix es como:

 -rw-r--r-- 1 user group 4467 Mar 27 2018 file1.zip -rw-r--r-- 1 user group 124529 Jun 18 15:31 file2.zip 

Con un listado como este, este código hará:

 from dateutil import parser # ... lines = [] ftp.dir("", lines.append) latest_time = None latest_name = None for line in lines: tokens = line.split(maxsplit = 9) time_str = tokens[5] + " " + tokens[6] + " " + tokens[7] time = parser.parse(time_str) if (latest_time is None) or (time > latest_time): latest_name = tokens[8] latest_time = time print(latest_name) 

Este es un enfoque bastante frágil.


MDTM

Una forma más confiable, pero menos eficiente, es usar el comando MDTM para recuperar marcas de tiempo de archivos / carpetas individuales:

 names = ftp.nlst() latest_time = None latest_name = None for name in names: time = ftp.voidcmd("MDTM " + name) if (latest_time is None) or (time > latest_time): latest_name = name latest_time = time print(latest_name) 

Interruptor no estándar -t

Algunos servidores FTP admiten un comando patentado no estándar -t para NLST (o LIST ).

 lines = ftp.nlst("-t") latest_name = lines[-1] 

Consulte Cómo obtener archivos en la carpeta FTP ordenados por hora de modificación .


Descargando el archivo encontrado

No importa qué enfoque utilice, una vez que tenga el latest_name , lo descarga como cualquier otro archivo:

 file = open(latest_name, 'wb') ftp.retrbinary('RETR '+ latest_name, file.write) 

Ver también

  • Obtén el último nombre de la carpeta FTP en Python
  • Cómo obtener el tiempo de modificación de un archivo FTP utilizando Python ftplib

No sé cómo es tu ftp, pero tu ejemplo no estaba funcionando para mí. Cambié algunas líneas relacionadas con la fecha de clasificación:

  import sys from ftplib import FTP import os import socket import time # Connects to the ftp ftp = FTP(ftpHost) ftp.login(yourUserName,yourPassword) data = [] datelist = [] filelist = [] ftp.dir(data.append) for line in data: col = line.split() datestr = ' '.join(line.split()[5:8]) date = time.strptime(datestr, '%b %d %H:%M') datelist.append(date) filelist.append(col[8]) combo = zip(datelist,filelist) who = dict(combo) for key in sorted(who.iterkeys(), reverse=True): print "%s: %s" % (key,who[key]) filename = who[key] print "file to download is %s" % filename try: ftp.retrbinary('RETR %s' % filename, open(filename, 'wb').write) except ftplib.err_perm: print "Error: cannot read file %s" % filename os.unlink(filename) else: print "***Downloaded*** %s " % filename ftp.quit()