在Python中递归列出FTP目录

3
我在检索远程FTP站点上的目录列表方面遇到了困难。这个答案不起作用(我没有输出,它似乎停滞了)。
以下是我能想到的最简单的实现方式 - 它应该只打印出它找到的每个目录的完整路径:
import ftplib

def ftp_walk(ftp):    
print 'Path:', ftp.pwd()
    dirs = ftp.nlst()
    for item in (path for path in dirs if path not in ('.', '..')):
        try:
            ftp.cwd(item)
            print 'Changed to', ftp.pwd()
            ftp_walk(ftp)
            ftp.cwd('..')
        except Exception, e:
            print item, e

ftp = ftplib.FTP('ftp.site.com')                                        
ftp.login('user', 'pass')
ftp.cwd('1')
ftp_walk(ftp)

我的目录结构如下:

1/
 1-1/
   1-2/
 1-2/
 1-3/
 1-4

然而,它只输出以下内容。它表明工作目录一次被更改为一个新的子目录,但是当ftp_walk()用新的cwd调用时,它不会再继续往下走:
> Path: 1/
> Changed to 1-1/

在哪个函数中它挂了?(您可以在代码中添加一些打印语句以查看它发生的位置) - thesamet
此外,您的代码在尝试 cwd 进入一个条目之前并未检查该条目是否为目录。 - thesamet
Eknath - 好问题;这是我的错误。然而,它产生了与列表推导相同的输出。 - cyrus
@EknathIyer 这是一个生成器表达式,并且它完全合法。它不会产生一个元组,而是一个可迭代对象,在需要时生成项目。话虽如此,更符合 Python 风格的做法可能是使用 for path in dirs:,然后 if path in ('.', '..'): continue,然后像以前一样继续进行。 - Karl Knechtel
当一个目录中有超过10个子目录时,它是否会挂起? - Rafael
显示剩余4条评论
2个回答

0

在构造函数之前的ftp.login('user', 'pass')和之后,您需要调用ftp.connect()


0

我猜测您正在登录的用户具有访问所有结构的权限,否则它将返回错误并且不会列出该特定目录。

如果您遇到异常,请在此处放置它。也许您应该try..finally您的cwd,以便它不会丢失。我可以建议:

    try:
        ftp.cwd(item)
        print 'Changed to', ftp.pwd()
        try:
            ftp_walk(ftp)
        finally:
            ftp.cwd('..')
    except ftplib.error_perm, e:
        print item, e

谢谢您的建议。我已经按照您的更改进行了修改,但它仍然停留在同一个地方。我对FTP上的目录进行了一些微小的更改,似乎只有在没有子目录的目录中才会出现这种情况。我不确定这意味着什么,如果有的话。 - cyrus
我最近遇到了卡顿的问题,除了网络权限(防火墙等)可能是原因之外,我无法找出其他原因。无论如何,打开/关闭被动模式都可以作为一种解决方法。 - augustomen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接