Pergunta

Você pode usar ftplib para suporte FTP completo em Python. No entanto, a maneira preferida de obter uma listagem de diretório é:

# 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 produz:

$ 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
...

Eu acho que a idéia é analisar os resultados para obter a listagem do diretório. No entanto, esta lista está directamente dependente da forma do servidor FTP da formatação da lista. Seria muito confuso para escrever código para isso ter que antecipar todas as maneiras diferentes servidores FTP pode formatar esta lista.

Existe uma maneira portátil para obter uma matriz preenchida com a lista do diretório?

(A matriz deve ter apenas os nomes das pastas.)

Foi útil?

Solução

Tente usar ftp.nlst(dir) .

No entanto, nota que, se a pasta está vazia, pode lançar um erro:

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

Outras dicas

A / maneira confiável padronizado para o diretório FTP parse lista é usando o comando MLSD, que agora deve ser apoiada por todos os servidores recentes / decente FTP.

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

O código acima irá 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 irá fornecer um método específico para fazer isso:

Eu encontrei o meu caminho aqui ao tentar obter nomes de arquivos, selos da última modificação, arquivo tamanhos etc e queria para adicionar meu código. Levou apenas alguns minutos para escrever um loop para analisar o ftp.dir(dir_list.append) fazendo uso de python std coisas lib como strip() (para limpar a linha de texto) e split() para criar uma 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']

Não há nenhum padrão para o layout da resposta LIST. Você teria que escrever código para lidar com os layouts mais populares. Eu começaria com ls Linux e formatos DIR do Windows Server. Há muita variedade lá fora, no entanto.

Queda de volta ao método nlst (retornando o resultado do comando NLST) se você não pode analisar a lista mais longa. Para pontos de bônus, enganar: talvez o número mais longo na linha que contém um nome de arquivo conhecidos é o seu comprimento.

Acontece que eu sou furado com um servidor de FTP (Rackspace Sites Nuvem servidor virtual) que não parecem apoiar MLSD. No entanto, eu preciso de vários campos de informações do arquivo, como tamanho e data e hora, e não apenas o nome do arquivo, então eu tenho que usar o comando DIR. Nesta servidor, a saída do DIR se parece muito com o OP é. Em caso de ajuda ninguém, aqui vai uma pequena classe Python que analisa uma linha de tal saída para obter o nome do arquivo, tamanho e data e hora.

import datetime

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')

Não é muito portátil, eu sei, mas fácil de estender ou modificar a lidar com vários servidores FTP diferentes.

Esta é a partir docs 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

Isso me ajudou com meu código.

Quando eu tentei feltering apenas uma tipo de arquivos e mostrar-los na tela, adicionando uma condição que os testes em cada linha.

Como este

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 em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top