Использование ftplib Python для получения списка каталогов, переносимо - PullRequest
51 голосов
/ 22 сентября 2008

Вы можете использовать ftplib для полной поддержки FTP в Python. Однако предпочтительный способ получения списка каталогов:

# 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.

Существует ли переносимый способ получить массив, заполненный списком каталогов?

(Массив должен содержать только имена папок.)

Ответы [ 7 ]

113 голосов
/ 22 сентября 2008

Попробуйте использовать ftp.nlst(dir).

Однако учтите, что если папка пуста, она может выдать ошибку:

files = []

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

for f in files:
    print f
24 голосов
/ 12 декабря 2011

Надежный / стандартизированный способ анализа списка каталогов 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 предоставит специальный метод для этого:

2 голосов
/ 15 августа 2017

Я нашел свой путь здесь, пытаясь найти имена файлов, последние измененные штампы, размеры файлов и т. Д., И хотел добавить свой код. Потребовалось всего несколько минут, чтобы написать цикл для синтаксического анализа 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']
2 голосов
/ 22 сентября 2008

Не существует стандарта для макета ответа LIST. Вам придется написать код для обработки самых популярных макетов. Я бы начал с форматов Linux ls и Windows Server DIR. Хотя есть много разнообразия.

Вернитесь к методу nlst (возвращающему результат команды NLST), если вы не можете проанализировать более длинный список. Для получения бонусных очков чит: возможно, самое длинное число в строке, содержащей известное имя файла, - это его длина.

1 голос
/ 07 июня 2014

Я застрял на FTP-сервере (виртуальный сервер Rackspace Cloud Sites), который, похоже, не поддерживает MLSD. Тем не менее, мне нужно несколько полей информации о файле, таких как размер и временная метка, а не только имя файла, поэтому я должен использовать команду 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-серверами.

0 голосов
/ 07 мая 2017

Это помогло мне с моим кодом.

Когда я попробовал валяться только типом файлов и показать их на экране, добавив условие, которое проверяет каждую строку.

Как это

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)
0 голосов
/ 06 мая 2017

Это из документов 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
...