Получение списка каталогов и файлов с помощью Python

Друзья, хотим поделиться с вами опытом решения одной из задач, поставленной перед нами. Нам требовалось подтвердить или опровергнуть предположение о нарушении технологии обработки данных в автоматизированной системе, а именно: проверить содержимое каталогов, размещенных на FTP-сервере, на наличие в них определенных файлов.

Для решения данной задачи мы использовали Python и его стандартный модуль ftplib.

Опишем, как мы это сделали. Для того, чтобы у вас была возможность попробовать самостоятельно проверить работу кода, мы опишем процесс на примере FTP-сервера Ростовского госуниверситета (ftp.rsu.ru).

Итак, начнем. Импортируем необходимые модули:

import ftplib import os from datetime import datetime

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

FTP_HOST = 'ftp.rsu.ur' FTP_USER = 'anonymous' FTP_PASS = ''

Далее используем вспомогательные функции, которые позволят вывести список «найденных» каталогов и файлов:

# некоторые служебные функции, которые нам понадобятся def get_size_format(n, suffix='B'): # преобразует байты в масштабированный формат (KB, MB, и т.д.) for unit in ['', 'K', 'M', 'G', 'T', 'P']: if n < 1024: return f'{n:.2f}{unit}{suffix}' n /= 1024 def get_datetime_format(date_time): # преобразовать в объект даты и времени date_time = datetime.strptime(date_time, '%Y%m%d%H%M%S') # преобразовать в удобочитаемую строку даты и времени return date_time.strftime('%Y/%m/%d %H:%M:%S')

Затем подключаемся к серверу, используя класс клиента FTP:

# инициализировать сеанс FTP ftp = ftplib.FTP(FTP_HOST, FTP_USER, FTP_PASS)

Для исключения проблем при работе с нелатинскими символами, изменим кодировку на UTF-8:

# принудительное кодирование UTF-8 ftp.encoding = 'utf-8'

Теперь, когда мы получили доступ к серверу, выведем приветственное сообщение, которое отправляется сервером после подключения (для уверенности, что мы оказались там, где надо 🙂

# вывести приветственное сообщение print(ftp.getwelcome())

Вот оно!

220 ProFTPD 1.3.5b Server (FTP Server of Rostov State University — only anonymous logins are allowed) [195.208.245.253]

После подключения к серверу мы находимся в корневом каталоге. Посмотрим на его содержимое, используя команду MLSD, с помощью которой получаем список каталогов и файлов с их метаданными: разрешение, размер, дата последней модификации и т. д.

print('*'*50, 'MLSD', '*'*50) # используем команду MLSD print('{:30} {:19} {:6} {:5} {:4} {:4} {:4} {}'.format('File Name', 'Last Modified', 'Size', 'Perm', 'Type', 'GRP', 'MODE', 'OWNER')) for file_data in ftp.mlsd(): # извлечь возвращаемые данные file_name, meta = file_data # т.е. каталог, файл или ссылка и т. д. file_type = meta.get('type') if file_type == 'file': # если это файл, изменить тип передаваемых данных на IMAGE / binary ftp.voidcmd('TYPE I') # получить размер файла в байтах file_size = ftp.size(file_name) # преобразовать его в удобочитаемый формат (т. е. в «КБ», «МБ» и т. д.) file_size = get_size_format(file_size) else: # не файл, то может быть каталог file_size = 'N/A' # дата последней модификации файла last_modified = get_datetime_format(meta.get('modify')) # права доступа к файлу permission = meta.get('perm') # получить id файла unique_id = meta.get('unique') # группа пользователей unix_group = meta.get('unix.group') # файловый режим, разрешения Unix unix_mode = meta.get('unix.mode') # владелец файла unix_owner = meta.get('unix.owner') # вывод результата print(f'{file_name:30} {last_modified} {file_size:7} {permission:5} {file_type:4} {unix_group:4} {unix_mode:4} {unix_owner}')

Вот результат работы команды MLSD:

************************************************** MLSD ************************************************** File Name Last Modified Size Perm Type GRP MODE OWNER . 2020/02/14 11:51:40 N/A fle cdir 35901 0644 0 .. 2020/02/14 11:51:40 N/A fle pdir 35901 0644 0 docsvisionclient 2016/08/01 13:36:22 N/A fle dir 35901 0644 37411 terminal 2011/09/24 18:22:19 N/A fle dir 35901 0644 0 Edu_tools 2011/09/24 18:23:15 N/A fle dir 35901 0644 0 Solaris 2020/03/31 21:15:57 N/A fle dir 35901 0644 0 net 2012/01/27 14:16:46 N/A fle dir 35901 0644 0 fujitsu 2017/09/11 14:32:06 N/A fle dir 35901 0644 0 security 2012/01/27 14:22:14 N/A fle dir 35901 0644 0 hardware 2011/09/24 18:15:29 N/A fle dir 35901 0644 0 development 2012/01/27 14:02:03 N/A fle dir 35901 0644 0 archivers 2011/09/24 18:38:42 N/A fle dir 35901 0644 0 databases 2012/01/27 13:59:13 N/A fle dir 35901 0644 0 telephony 2011/09/24 18:26:25 N/A fle dir 35901 0644 0 desktop 2013/12/05 18:12:14 N/A fle dir 35901 0644 0 video 2014/03/12 08:32:36 N/A fle dir 25512 0644 35422 media 2011/09/24 18:19:13 N/A fle dir 35901 0644 0 publishing 2012/01/27 14:20:54 N/A fle dir 35901 0644 0 shells 2011/09/24 18:19:33 N/A fle dir 35901 0644 0 linux 2018/04/20 05:22:10 N/A fle dir 35901 0644 0 local 2011/09/24 18:04:29 N/A fle dir 35901 0644 0 bacula 2015/09/21 08:00:37 N/A fle dir 35901 0644 35428 ccm 2011/09/24 18:21:47 N/A fle dir 35901 0644 0 patches 2014/08/11 18:26:39 N/A fle dir 35901 0644 0 gparted 2014/09/16 12:06:29 N/A fle dir 35901 0644 0 public 2013/06/07 13:11:38 N/A adfr OS.unix=symlink 35901 0644 0 office 2012/01/27 14:17:31 N/A fle dir 35901 0644 0 text 2011/09/24 18:19:33 N/A fle dir 35901 0644 0 sysutils 2011/09/24 18:22:36 N/A fle dir 35901 0644 0 FreeBSD 2020/02/14 12:07:50 N/A fle dir 0 0644 0

Далее, если потребуется сменить текущий каталог на какой-либо другой, например pub/maps, чтобы проверить его содержимое, используем команду cwd:

# изменить текущий рабочий каталог на каталог «pub» и подкаталог «maps» ftp.cwd("linux/debian")

Если все ОК, получим сообщение:

‘250 CWD command successful’

Теперь можно повторить выполнение MLSD и вот содержимое ее работы

************************************************** MLSD ************************************************** File Name Last Modified Size Perm Type GRP MODE OWNER . 2020/05/13 10:51:46 N/A fle cdir 35901 0644 0 .. 2018/04/20 05:22:10 N/A fle pdir 35901 0644 0 firmware-10.4.0-amd64-DVD-1.iso 2020/05/09 12:00:00 3.69GB adfr file 0 0644 0 firmware-9.3.0-amd64-DVD-1.iso 2017/12/09 13:09:55 3.39GB adfr file 35901 0644 0 debian-7.6.0-amd64-CD-1.iso 2014/09/09 07:48:00 635.00MB adfr file 35901 0644 44185 ql.iso 2015/06/11 08:35:21 602.00KB adfr file 1000 0644 1000 firmware-qlogic_20190717-2_all.iso 2020/05/13 10:51:46 3.38MB adfr file 0 0644 0 debian-8.4.0-amd64-CD-1.iso 2016/04/02 16:06:34 630.00MB adfr file 35901 0644 0 firmware.iso 2020/05/13 10:34:11 4.22MB adfr file 35901 0644 39622

После окончания работы с FTP-сервером закрываем соединение:

# выйти и закрыть соединение ftp.quit()

В результате: '221 Goodbye.'

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

0
Комментарии
-3 комментариев
Раскрывать всегда