70

您可以使用 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
...

我想这个想法是解析结果以获取目录列表。但是,此列表直接取决于 FTP 服务器格式化列表的方式。必须预测 FTP 服务器可能会格式化此列表的所有不同方式,为此编写代码会非常麻烦。

是否有一种可移植的方式来获取一个充满目录列表的数组?

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

4

7 回答 7

139

尝试使用ftp.nlst(dir).

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

files = []

try:
    files = ftp.nlst()
except ftplib.error_perm as resp:
    if str(resp) == "550 No files found":
        print "No files in this directory"
    else:
        raise

for f in files:
    print f
于 2008-09-21T20:15:59.517 回答
33

解析 FTP 目录列表的可靠/标准化方法是使用 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 将提供一个特定的方法来做到这一点:

于 2011-12-12T13:10:19.507 回答
7

我在尝试获取文件名、最后修改的戳记、文件大小等时在这里找到了我的方式,并想添加我的代码。只花了几分钟就编写了一个循环来解析ftp.dir(dir_list.append)使用 python std lib 的东西,比如strip()(清理文本行)并split()创建一个数组。

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']
于 2017-08-14T22:52:07.497 回答
2

LIST响应的布局没有标准。您必须编写代码来处理最流行的布局。我将从 Linuxls和 Windows ServerDIR格式开始。不过,那里有很多种类。

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

于 2008-09-21T20:20:36.417 回答
1

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

导入日期时间

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 服务器。

于 2014-06-06T20:50:39.497 回答
0

这是来自 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
于 2017-05-06T08:46:45.843 回答
0

这对我的代码有帮助。

当我尝试仅对一种文件进行毡化并通过添加在每一行上进行测试的条件将它们显示在屏幕上时。

像这样

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)
于 2017-05-07T11:03:39.617 回答