如何让Python检查ftp目录是否存在?

时间:2009-07-08 13:51:56

标签: python ftp

我正在使用此脚本连接到示例ftp服务器并列出可用目录:

from ftplib import FTP
ftp = FTP('ftp.cwi.nl')   # connect to host, default port (some example server, i'll use other one)
ftp.login()               # user anonymous, passwd anonymous@
ftp.retrlines('LIST')     # list directory contents
ftp.quit()

如何使用ftp.retrlines('LIST')输出检查目录(例如public_html)是否存在,是否存在cd,然后执行其他代码并退出;如果不立即执行代码并退出?

8 个答案:

答案 0 :(得分:17)

Nslt将为ftp服务器中的所有文件列出一个数组。只需检查您的文件夹名称是否存在。

from ftplib import FTP 
ftp = FTP('yourserver')
ftp.login('username', 'password')

folderName = 'yourFolderName'
if folderName in ftp.nlst():
    #do needed task 

答案 1 :(得分:10)

您可以使用列表。示例

import ftplib
server="localhost"
user="user"
password="test@email.com"
try:
    ftp = ftplib.FTP(server)    
    ftp.login(user,password)
except Exception,e:
    print e
else:    
    filelist = [] #to store all files
    ftp.retrlines('LIST',filelist.append)    # append to list  
    f=0
    for f in filelist:
        if "public_html" in f:
            #do something
            f=1
    if f==0:
        print "No public_html"
        #do your processing here

答案 2 :(得分:4)

您可以通过控制连接发送“MLST路径”。 这将返回包含路径的类型的行(此处注意'type = dir'):

250-Listing "/home/user":
 modify=20131113091701;perm=el;size=4096;type=dir;unique=813gc0004; /
250 End MLST.

转换为python应该是这些方面的东西:

import ftplib
ftp = ftplib.FTP()
ftp.connect('ftp.somedomain.com', 21)
ftp.login()
resp = ftp.sendcmd('MLST pathname')
if 'type=dir;' in resp:
    # it should be a directory
    pass

当然上面的代码不是100%可靠,需要一个“真正的”解析器。 您可以在ftplib.py中查看MLSD命令的实现,它非常相似(MLSD与MLST的不同之处在于通过 data 连接发送的响应,但是传输的行的格式是相同的): http://hg.python.org/cpython/file/8af2dc11464f/Lib/ftplib.py#l577

答案 3 :(得分:3)

ghostdog74的答案附带的例子有一点错误:你得到的列表是响应的整行,所以你得到类似的东西

drwxrwxrwx    4 5063     5063         4096 Sep 13 20:00 resized

这意味着如果您的目录名称类似于“50”(在我的情况下),您将得到误报。我修改了代码来处理这个问题:

def directory_exists_here(self, directory_name):
    filelist = []
    self.ftp.retrlines('LIST',filelist.append)
    for f in filelist:
        if f.split()[-1] == directory_name:
            return True
    return False

N.B。,这是我编写的FTP包装器类,self.ftp是实际的FTP连接。

答案 4 :(得分:1)

汤姆是对的,但没有人投票给他 然而,为了满足谁投票了ghostdog74我将混合和编写这个代码,适合我,应该适合你们。

import ftplib
server="localhost"
user="user"
uploadToDir="public_html"
password="test@email.com"
try:
    ftp = ftplib.FTP(server)    
    ftp.login(user,password)
except Exception,e:
    print e
else:    
    filelist = [] #to store all files
    ftp.retrlines('NLST',filelist.append)    # append to list  
    num=0
    for f in filelist:
        if f.split()[-1] == uploadToDir:
            #do something
            num=1
    if num==0:
        print "No public_html"
        #do your processing here

首先,如果你遵循鬼狗方法,即使你在f中说目录“公共”,即使它不存在,它也会评估为真,因为公共单词public存在于“public_html”中,所以汤姆如果条件可以使用 所以如果f.split()[ - 1] == uploadToDir:,我将其更改为

此外,如果你输入的目录名称somethig不存在,但存在一些文件和文件夹,第二个由ghostdog74永远不会执行,因为它永远不会被f in循环覆盖,所以我使用了 num 变量取而代之的是 f ,而且好了... ...

Vinay和Jonathon对他们的评论是对的。

答案 5 :(得分:1)

在3.x nlst()方法中已弃用。使用此代码:

import ftplib

remote = ftplib.FTP('example.com')
remote.login()

if 'foo' in [name for name, data in list(remote.mlsd())]:
    # do your stuff

需要list()调用,因为mlsd()会返回一个生成器并且不支持检查其中的内容(没有__contains__()方法)。

您可以将[name for name, data in list(remote.mlsd())] list comp包装在方法函数中,并在需要检查目录(或文件)是否存在时调用它。

答案 6 :(得分:1)

=>我在google搜索这个网页的同时检查文件是否存在使用python中的ftplib。以下是我想到的(希望它可以帮助某人):

=>在尝试列出不存在的文件/目录时,ftplib会引发异常。即使添加一个try / except块是一个标准的做法和一个好主意,我希望我的FTP脚本只有在确定它们存在后才能下载文件。这有助于保持我的脚本更简单 - 至少在FTP服务器上列出目录是可能的。

例如,Edgar FTP服务器有多个文件存储在/ edgar / daily-index /目录下。每个文件都被命名为“master.YYYYMMDD.idx”。无法保证每个日期都存在一个文件(YYYYMMDD) - 没有日期为2013年11月24日的文件,但是有一个日期为2013年11月22日的文件。这两种情况下的列表如何工作?

# Code
from __future__ import print_function  
import ftplib  

ftp_client = ftplib.FTP("ftp.sec.gov", "anonymous", "MY.EMAIL@gmail.com")  
resp = ftp_client.sendcmd("MLST /edgar/daily-index/master.20131122.idx")  
print(resp)   
resp = ftp_client.sendcmd("MLST /edgar/daily-index/master.20131124.idx")  
print(resp)  

# Output
250-Start of list for /edgar/daily-index/master.20131122.idx  
modify=20131123030124;perm=adfr;size=301580;type=file;unique=11UAEAA398;  
UNIX.group=1;UNIX.mode=0644;UNIX.owner=1019;  
/edgar/daily-index/master.20131122.idx
250 End of list  

Traceback (most recent call last):
File "", line 10, in <module>
resp = ftp_client.sendcmd("MLST /edgar/daily-index/master.20131124.idx")
File "lib/python2.7/ftplib.py", line 244, in sendcmd
return self.getresp()
File "lib/python2.7/ftplib.py", line 219, in getresp
raise error_perm, resp
ftplib.error_perm: 550 '/edgar/daily-index/master.20131124.idx' cannot be listed

正如所料,列出不存在的文件会产生异常。

=&GT;因为我知道Edgar FTP服务器肯定会有目录/ edgar / daily-index /,所以我的脚本可以执行以下操作以避免因文件不存在而引发异常:
a)列出这个目录 b)下载所需文件(如果它们存在于此列表中) - 要检查列表,我通常在列表操作返回的字符串列表上执行正则表达式搜索。

例如,此脚本会尝试下载过去三天的文件。如果找到某个日期的文件,则下载该文件,否则没有任何反应。

import ftplib
import re
from datetime import date, timedelta

ftp_client = ftplib.FTP("ftp.sec.gov", "anonymous", "MY.EMAIL@gmail.com")
listing = []
# List the directory and store each directory entry as a string in an array
ftp_client.retrlines("LIST /edgar/daily-index", listing.append)
# go back 1,2 and 3 days
for diff in [1,2,3]:
  today = (date.today() - timedelta(days=diff)).strftime("%Y%m%d")
  month = (date.today() - timedelta(days=diff)).strftime("%Y_%m")
  # the absolute path of the file we want to download - if it indeed exists
  file_path = "/edgar/daily-index/master.%(date)s.idx" % { "date": today }
  # create a regex to match the file's name
  pattern = re.compile("master.%(date)s.idx" % { "date": today })
  # filter out elements from the listing that match the pattern
  found = filter(lambda x: re.search(pattern, x) != None, listing)
  if( len(found) > 0 ):
    ftp_client.retrbinary(
      "RETR %(file_path)s" % { "file_path": file_path },
      open(
        './edgar/daily-index/%(month)s/master.%(date)s.idx' % {
          "date": today
        }, 'wb'
      ).write
    )

=&GT;有趣的是,有些情况下我们无法在FTP服务器上列出目录。例如,edgar FTP服务器不允许在/ edgar / data上列出,因为它包含太多的子目录。在这种情况下,我将无法使用此处描述的“列表和检查存在”方法 - 在这些情况下,我将不得不在我的下载程序脚本中使用异常处理来从不存在的文件/目录访问尝试中恢复。

答案 7 :(得分:0)

from ftplib import FTP

ftp = FTP()
ftp.connect(hostname, 21) 
ftp.login(username,password)

try:
    ftp.cwd('your folder name')
    #do the code for successfull cd
except Exception:
    #do the code for folder not exists