我正在使用此脚本连接到示例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,然后执行其他代码并退出;如果不立即执行代码并退出?
答案 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)
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