Vous pouvez utiliser ftplib pour une prise en charge FTP complète en Python. Cependant, la manière préférée 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 du serveur FTP de formater la liste. Il serait très compliqué d'écrire du code pour que cela ait à anticiper toutes les différentes façons dont les serveurs FTP pourraient formater cette liste.
Existe-t-il un moyen portable d'obtenir un tableau rempli avec la liste des répertoires?
(Le tableau ne doit avoir que les noms de dossier.)
Essayez d'utiliser ftp.nlst(dir)
.
Cependant, notez que si le dossier est vide, il peut générer une erreur:
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
La manière fiable/standardisée 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 imprimera:
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 ce 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. Il n'a fallu que quelques minutes pour écrire une boucle pour analyser la ftp.dir(dir_list.append)
en utilisant python std lib stuff comme strip()
(pour 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 norme pour la disposition de la réponse LIST
. Vous devez écrire du code pour gérer les mises en page les plus populaires. Je commencerais par les formats Linux ls
et Windows Server DIR
. Il y a cependant beaucoup de variété.
Revenez à la méthode nlst
(renvoyant le résultat de la commande NLST
) si vous ne pouvez pas analyser la liste plus longue. Pour les points bonus, triche: le nombre le plus long de la ligne contenant un nom de fichier connu est peut-être sa longueur.
Il se trouve que 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 les fichiers, tels que la taille et l'horodatage, pas seulement le nom du fichier, donc je dois utiliser la commande DIR. Sur ce serveur, la sortie de DIR ressemble beaucoup aux OP. Dans le cas où cela aiderait quelqu'un, voici une petite classe Python qui analyse une ligne de cette sortie pour obtenir le nom de fichier, la taille et l'horodatage.
importer 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')
Pas très portable, je sais, mais facile à étendre ou à modifier pour gérer différents serveurs FTP différents.
Cela vient de Python docs
>>> 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 sur chaque ligne.
Comme ça
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)