使用Python的ftplib获取一个目录列表,可移植的

您可以使用ftplib在Python中提供完整的FTP支持。 但是获取目录列表的首选方式是:

# 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 

这产生:

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

我想这个想法是parsing结果来获取目录列表。 但是,这个列表直接依赖于FTP服务器格式化列表的方式。 为此编写代码将是非常混乱的,不得不预测FTP服务器可能对这个列表进行格式化的所有不同方式。

有一种可移植的方式来获得一个数组填充目录列表?

(数组只能有文件夹名称。)

尝试使用ftp.nlst(dir)

但是请注意,如果该文件夹为空,则可能会引发错误:

 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 

parsingFTP目录列表的可靠/标准化的方法是使用MLSD命令,现在应该由所有最近/正常的FTP服务器来支持。

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

上面的代码将打印:

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

从python 3.3开始,ftplib将提供一个特定的方法来执行此操作:

LIST响应的布局没有标准。 你必须编写代码来处理最stream行的布局。 我将从Linux ls和Windows Server DIR格式开始。 虽然有很多种类。

如果无法parsing长列表,则回退到nlst方法(返回NLST命令的结果)。 对于奖励积分,作弊:也许包含已知文件名的行中最长的数字是其长度。

我碰巧遇到了似乎不支持MLSD的FTP服务器(Rackspace Cloud Sites虚拟服务器)。 然而,我需要几个字段的文件信息,如大小和时间戳,不只是文件名,所以我必须使用DIR命令。 在这台服务器上,DIR的输出看起来非常像OP。 如果它帮助任何人,这是一个小的Python类,parsing一行这样的输出,以获得文件名,大小和时间戳。

导入date时间

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

我知道,不是很便携,但容易扩展或修改处理各种不同的FTP服务器。

这是来自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 

这帮助了我的代码。

当我试图只恶化一种types的文件,并在屏幕上显示他们添加一个条件,在每一行的testing。

喜欢这个

 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) 

我试图获取文件名,最后修改的邮票,文件大小等,并想添加我的代码,我在这里find了我的方式。 它只花了几分钟的时间来编写一个循环来parsingftp.dir(dir_list.append) ,利用python std lib的东西像strip() (清理文本行)和split()创build一个数组。

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