Utiliser ftplib de Python pour obtenir une liste de répertoires, de manière portable

StackOverflow https://stackoverflow.com/questions/111954

  •  02-07-2019
  •  | 
  •  

Question

Vous pouvez utiliser ftplib pour une prise en charge complète de FTP en Python. Cependant, le moyen privilégié d’obtenir une liste de répertoires est:

# 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

Ce qui donne:

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

Je suppose que l’idée est d’analyser les résultats pour obtenir la liste des répertoires. Cependant, cette liste dépend directement de la manière dont le serveur FTP a formaté la liste. Il serait très désordonné d’écrire du code car il faut anticiper les différentes manières dont les serveurs FTP peuvent formater cette liste.

Existe-t-il un moyen portable d'obtenir un tableau rempli avec la liste de répertoires?

(Le tableau ne doit contenir que les noms de dossier.)

Était-ce utile?

La solution

Essayez d'utiliser ftp.nlst (dir) .

Cependant, notez que si le dossier est vide, une erreur risque de se produire:

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

Autres conseils

Le moyen fiable / normalisé d’analyser la liste des répertoires FTP consiste à utiliser la commande MLSD, qui devrait désormais être prise en charge par tous les serveurs FTP récents / corrects.

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

Le code ci-dessus sera imprimé:

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

À partir de python 3.3, ftplib fournira une méthode spécifique pour le faire:

J'ai trouvé mon chemin ici en essayant d'obtenir les noms de fichiers, les derniers tampons modifiés, les tailles de fichiers, etc. et je voulais ajouter mon code. Quelques minutes seulement ont été nécessaires pour écrire une boucle afin d’analyser le ftp.dir (dir_list.append) en utilisant des éléments python std lib tels que strip () (pour les nettoyer). la ligne de texte) et split () pour créer un tableau.

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

Il n'y a pas de standard pour la présentation de la réponse LIST . Vous devez écrire du code pour gérer les dispositions les plus populaires. Je commencerais par les formats Linux ls et Windows Server DIR . Il y a cependant beaucoup de variété.

Retournez à la méthode nlst (en renvoyant le résultat de la commande NLST ) si vous ne pouvez pas analyser la liste plus longue. Pour les points bonus, trichez: le nombre le plus long de la ligne contenant un nom de fichier connu est peut-être sa longueur.

Je suis coincé avec un serveur FTP (serveur virtuel Rackspace Cloud Sites) qui ne semble pas prendre en charge MLSD. Pourtant, j'ai besoin de plusieurs champs d'informations sur le fichier, tels que la taille et l'horodatage, et pas seulement le nom du fichier. Je dois donc utiliser la commande DIR. Sur ce serveur, la sortie de DIR ressemble beaucoup à celle de l'OP. Si cela peut aider quelqu'un, voici une petite classe Python qui analyse une ligne de cette sortie pour obtenir le nom du fichier, sa taille et son horodatage.

importer date / heure

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

Pas très portable, je sais, mais facile à étendre ou à modifier pour traiter avec différents serveurs FTP.

Ceci est issu de la documentation 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

Cela m'a aidé avec mon code.

Lorsque j'ai essayé de filtrer uniquement un type de fichiers et de les afficher à l'écran en ajoutant une condition qui teste chaque ligne.

Comme ceci

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)
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top