Как сделать Python проверкой, существует ли каталог ftp?
Я использую этот script для подключения к образцу 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 [email protected]
ftp.retrlines('LIST') # list directory contents
ftp.quit()
Как использовать вывод ftp.retrlines('LIST'), чтобы проверить, существует ли каталог (например, public_html), если он существует cd, а затем выполнить другой код и выйти; если не выполнить код сразу и выйти?
Ответы
Ответ 1
Nslt отобразит массив для всех файлов на ftp-сервере. Просто проверьте, существует ли ваше имя папки.
from ftplib import FTP
ftp = FTP('yourserver')
ftp.login('username', 'password')
folderName = 'yourFolderName'
if folderName in ftp.nlst():
#do needed task
Ответ 2
вы можете использовать список. Пример
import ftplib
server="localhost"
user="user"
password="[email protected]"
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
Ответ 3
Вы можете отправить "путь MLST" по управляющему соединению.
Это вернет строку, включающую тип пути (см. Здесь "type = dir" ):
250-Listing "/home/user":
modify=20131113091701;perm=el;size=4096;type=dir;unique=813gc0004; /
250 End MLST.
Переведенный на питон, который должен быть чем-то следующим:
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% надежный и нуждается в "реальном" синтаксическом анализаторе.
Вы можете посмотреть на реализацию команды MLSD в ftplib.py, которая очень похожа (MLSD отличается от MLST тем, что ответ отправлен по соединению данных, но формат передаваемых строк одинаковый):
http://hg.python.org/cpython/file/8af2dc11464f/Lib/ftplib.py#l577
Ответ 4
В примерах, связанных с ответом 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-соединением.
Ответ 5
Том прав, но никто не проголосовал за него
однако для удовлетворения, кто голосовал за ghostdog74, я буду смешивать и писать этот код, работает для меня, должен работать для вас, ребята.
import ftplib
server="localhost"
user="user"
uploadToDir="public_html"
password="[email protected]"
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
в первую очередь, если вы следуете методу призрачной собаки, даже если вы скажете, что каталог "public" в f, даже если он не существует, он будет оценивать true, потому что слово public существует в "public_html", так что там, где Tom, если условие использоваться
поэтому я изменил его на , если f.split() [- 1] == uploadToDir:.
Также, если вы введете имя каталога somethig, которое не существует, но некоторые файлы и папка существуют, второй из ghostdog74 никогда не будет выполняться, потому что его никогда не 0 как переопределенный f в цикле for, поэтому я использовал num variable вместо f и voila goodness следует...
Винай и Джонатон справедливы в отношении того, что они прокомментировали.
Ответ 6
В 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 в функцию метода и вызвать его, когда вам нужно просто проверить, существует ли каталог (или файл).
Ответ 7
= > Я нашел эту веб-страницу во время поиска по пути, чтобы проверить, существует ли файл с использованием ftplib в python. Следующее - это то, что я понял (надеюсь, что это помогает кому-то):
= > При попытке перечислить несуществующие файлы/каталоги, ftplib вызывает исключение. Несмотря на то, что добавление блока try/except является стандартной практикой и хорошей идеей, я бы предпочел, чтобы мои FTP-скрипты загружали файлы (файлы) только после того, как они были уверены. Это помогает упростить мои сценарии - по крайней мере, когда список каталогов на FTP-сервере возможен.
Например, FTP-сервер Edgar имеет несколько файлов, которые хранятся в каталоге /edgar/daily -index/. Каждый файл называется "master.YYYYMMDD.idx". Нет никакой гарантии, что файл будет существовать на каждую дату (YYYYMMDD) - нет файла от 24 ноября 2013 года, но есть файл от 22 ноября 2013 года. Как листинг работает в этих двух случаях?
# Code
from __future__ import print_function
import ftplib
ftp_client = ftplib.FTP("ftp.sec.gov", "anonymous", "[email protected]")
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
Как и ожидалось, перечисление несуществующего файла генерирует исключение.
= > Поскольку я знаю, что FTP-сервер Edgar, безусловно, будет иметь каталог /edgar/daily -index/, мой script может сделать следующее, чтобы избежать привлечения исключений из-за несуществующих файлов:
a) перечислите этот каталог.
b) загрузить требуемый файл (ы), если они есть в этом списке. Чтобы проверить листинг, я обычно выполняю поиск в регулярном выражении в списке строк, возвращаемых операцией листинга.
Например, этот script пытается загрузить файлы за последние три дня. Если файл найден на определенную дату, он загружается, иначе ничего не происходит.
import ftplib
import re
from datetime import date, timedelta
ftp_client = ftplib.FTP("ftp.sec.gov", "anonymous", "[email protected]")
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 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
)
= > Интересно, что есть ситуации, когда мы не можем перечислить каталог на FTP-сервере. Например, FTP-сервер edgar запрещает перечисление в /edgar/data, поскольку он содержит слишком много подкаталогов. В таких случаях я не смог бы использовать описанный здесь подход "Список и проверка на существование" - в этих случаях мне пришлось бы использовать обработку исключений в моем загрузчике script для восстановления из несуществующего доступа к файлу/каталогу попытки.
Ответ 8
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