Pregunta

Puede utilizar ftplib para obtener compatibilidad total con FTP en Python.Sin embargo, la forma preferida de obtener un listado en un directorio es:

# 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

Cuyos rendimientos:

$ 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 del directorio.Sin embargo, esta lista depende directamente de la forma en que el servidor FTP formatea la lista.Sería muy complicado escribir código para esto teniendo que anticipar todas las diferentes formas en que los servidores FTP podrían formatear esta lista.

¿Existe una forma portátil de completar una matriz con la lista del directorio?

(La matriz solo debe tener los nombres de las carpetas).

¿Fue útil?

Solución

Tratar de usar ftp.nlst(dir).

Sin embargo, tenga en cuenta que si la carpeta está vacía, podría generar 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

Otros consejos

La forma confiable/estandarizada de analizar la lista de directorios FTP es mediante el uso del comando MLSD, que a estas alturas debería 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 se 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:

Encontré mi camino hasta aquí mientras intentaba obtener nombres de archivos, últimos sellos modificados, tamaños de archivos, etc. y quería agregar mi código.Sólo tomó unos minutos escribir un bucle para analizar el ftp.dir(dir_list.append) haciendo uso de cosas de python std lib como 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']

No existe un estándar para el diseño del LIST respuesta.Tendrías que escribir código para manejar los diseños más populares.Yo empezaría con Linux ls y servidor de windows DIR formatos.Aunque hay mucha variedad por ahí.

Regresar a la nlst método (que devuelve el resultado de la NLST comando) si no puede analizar la lista más larga.Para obtener puntos de bonificación, haga trampa:Quizás el número más largo en la línea que contiene un nombre de archivo conocido sea su longitud.

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

importar fecha y hora

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 es muy portátil, lo sé, pero es fácil de ampliar o modificar para que funcione con varios servidores FTP diferentes.

Esto es de documentos 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

Eso me ayudó con mi código.

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

Como esto

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)
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top