2008-09-21 35 views
44

Puede usar ftplib para soporte completo de FTP en Python. Sin embargo, la mejor forma de conseguir un listado de directorio es:Usando el ftplib de Python para obtener una lista de directorios, portably

# File: ftplib-example-1.py 

import ftplib 

ftp = ftplib.FTP("www.python.org") 
ftp.login("anonymous", "ftplib-example-1") 

data = [] 

ftp.dir(data.append) 

ftp.quit() 

for line in data: 
    print "-", line 

que produce:

$ python ftplib-example-1.py 
- total 34 
- drwxrwxr-x 11 root  4127   512 Sep 14 14:18 . 
- drwxrwxr-x 11 root  4127   512 Sep 14 14:18 .. 
- drwxrwxr-x 2 root  4127   512 Sep 13 15:18 RCS 
- lrwxrwxrwx 1 root  bin   11 Jun 29 14:34 README -> welcome.msg 
- drwxr-xr-x 3 root  wheel  512 May 19 1998 bin 
- drwxr-sr-x 3 root  1400   512 Jun 9 1997 dev 
- drwxrwxr-- 2 root  4127   512 Feb 8 1998 dup 
- drwxr-xr-x 3 root  wheel  512 May 19 1998 etc 
... 

supongo que la idea es analizar los resultados para obtener el listado de directorios. Sin embargo, esta lista depende directamente de la manera en que el servidor FTP formatee la lista. Sería muy complicado escribir código para tener que anticipar todas las formas diferentes en que los servidores FTP podrían formatear esta lista.

¿Hay alguna manera portátil de obtener una matriz con la lista del directorio?

(La matriz debe tener sólo los nombres de las carpetas.)

Respuesta

94

intenta utilizar ftp.nlst(dir).

Sin embargo, tenga en cuenta que si la carpeta está vacía, podría lanzar un error:

files = [] 

try: 
    files = ftp.nlst() 
except ftplib.error_perm, resp: 
    if str(resp) == "550 No files found": 
     print "No files in this directory" 
    else: 
     raise 

for f in files: 
    print f 
+2

¡Oh, bien visto en el 550! Upvoted. :) –

+3

sí, esto responde la pregunta, y creo que es genial, pero no es una respuesta totalmente ampliable. ¿y si necesito un objeto de archivo con propiedades? no ser pesimista, pero sería útil. –

+10

Gracias por esto. 5 años después: obsoleto desde la versión 3.3: use mlsd() en su lugar. –

2

no hay un estándar para el diseño de la respuesta LIST. Tendría que escribir código para manejar los diseños más populares. Comenzaría con los formatos Linux ls y Windows Server DIR. Sin embargo, hay mucha variedad.

Vuelva al método nlst (devolviendo el resultado del comando NLST) si no puede analizar la lista más larga. Para los puntos de bonificación, trampa: quizás el número más largo en la línea que contiene un nombre de archivo conocido es su longitud.

+8

Nunca jamás deberías asumir eso. Adivinar siempre conduce a errores absolutos cuando menos te lo esperas – iElectric

+0

Muy cierto, de ahí mis muchas pruebas unitarias y pruebas de integración. :) Sin embargo, si necesitan la longitud, es: espera que el formato coincida con uno de los que han probado; descanso; o intenta averiguar dónde encontrar la longitud. Ninguna de las opciones es ideal. –

24

La manera confiable/estandarizada para analizar la lista de directorios FTP es mediante el uso del comando MLSD, que ahora debe ser compatible con todos los servidores FTP recientes/decentes.

import ftplib 
f = ftplib.FTP() 
f.connect("localhost") 
f.login() 
ls = [] 
f.retrlines('MLSD', ls.append) 
for entry in ls: 
    print entry 

El código anterior imprimir:

modify=20110723201710;perm=el;size=4096;type=dir;unique=807g4e5a5; tests 
modify=20111206092323;perm=el;size=4096;type=dir;unique=807g1008e0; .xchat2 
modify=20111022125631;perm=el;size=4096;type=dir;unique=807g10001a; .gconfd 
modify=20110808185618;perm=el;size=4096;type=dir;unique=807g160f9a; .skychart 
... 

A partir de Python 3.3, ftplib proporcionará un método específico para hacer esto:

0

Sucede que estoy atascado con un servidor FTP (servidor virtual Rackspace Cloud Sites) que no parece ser compatible con MLSD. Sin embargo, necesito varios campos de información de archivos, como el tamaño y la marca de tiempo, no solo el nombre del archivo, así que tengo que usar el comando DIR. En este servidor, la salida de DIR se parece mucho a la OP. En caso de que ayude a alguien, aquí hay una pequeña clase de Python que analiza una línea de tal salida para obtener el nombre de archivo, el tamaño y la marca de tiempo.

fecha y hora de importación

class FtpDir: 
    def parse_dir_line(self, line): 
     words = line.split() 
     self.filename = words[8] 
     self.size = int(words[4]) 
     t = words[7].split(':') 
     ts = words[5] + '-' + words[6] + '-' + datetime.datetime.now().strftime('%Y') + ' ' + t[0] + ':' + t[1] 
     self.timestamp = datetime.datetime.strptime(ts, '%b-%d-%Y %H:%M') 
No

muy portable, lo sé, pero es fácil de ampliar o modificar para hacer frente a diversos servidores FTP distintos.

0

Esto es de documentación de Python

>>> from ftplib import FTP_TLS 
>>> ftps = FTP_TLS('ftp.python.org') 
>>> ftps.login()   # login anonymously before securing control 
channel 
>>> ftps.prot_p()   # switch to secure data connection 
>>> ftps.retrlines('LIST') # list directory content securely 
total 9 
drwxr-xr-x 8 root  wheel  1024 Jan 3 1994 . 
drwxr-xr-x 8 root  wheel  1024 Jan 3 1994 .. 
drwxr-xr-x 2 root  wheel  1024 Jan 3 1994 bin 
drwxr-xr-x 2 root  wheel  1024 Jan 3 1994 etc 
d-wxrwxr-x 2 ftp  wheel  1024 Sep 5 13:43 incoming 
drwxr-xr-x 2 root  wheel  1024 Nov 17 1993 lib 
drwxr-xr-x 6 1094  wheel  1024 Sep 13 19:07 pub 
drwxr-xr-x 3 root  wheel  1024 Jan 3 1994 usr 
-rw-r--r-- 1 root  root   312 Aug 1 1994 welcome.msg 
0

que me ayudó con mi código.

Cuando traté de identificar solo un tipo de archivos y mostrarlos en la pantalla agregando una condición que prueba en cada línea.

gusta esta

elif command == 'ls': 
    print("directory of ", ftp.pwd()) 
    data = [] 
    ftp.dir(data.append) 

    for line in data: 
     x = line.split(".") 
     formats=["gz", "zip", "rar", "tar", "bz2", "xz"] 
     if x[-1] in formats: 
      print ("-", line) 
-1

he encontrado mi camino aquí al intentar obtener los nombres de archivo, sellos últimos modificados, tamaños de archivo, etc., y quería añadir mi código. Solo tomó unos minutos escribir un ciclo para analizar el ftp.dir(dir_list.append) haciendo uso de cosas como python lib strip() (para limpiar la línea de texto) y split() para crear una matriz.

ftp = FTP('sick.domain.bro') 
ftp.login() 
ftp.cwd('path/to/data') 

dir_list = [] 
ftp.dir(dir_list.append) 

# main thing is identifing which char marks start of good stuff 
# '-rw-r--r-- 1 ppsrt ppsrt  545498 Jul 23 12:07 FILENAME.FOO 
#        ^(that is line[29]) 

for line in dir_list: 
    print line[29:].strip().split(' ') # got yerself an array there bud! 
    # EX ['545498', 'Jul', '23', '12:07', 'FILENAME.FOO'] 
Cuestiones relacionadas