Уведомления

Группа в Telegram: @pythonsu

#1 Янв. 17, 2019 23:25:03

VIRTOK
Зарегистрирован: 2017-10-23
Сообщения: 77
Репутация: +  0  -
Профиль   Отправить e-mail  

Функция для рекурсивной загрузки каталога по SFTP

Нужна функция для рекурсивной загрузки каталога с SFTP
Прошу помочь разобраться как работает функция

 import paramiko, os
paramiko.util.log_to_file('/tmp/paramiko.log')
from stat import S_ISDIR
host = "ip"
port = 22
transport = paramiko.Transport((host, port))
password = "mypassword"
username = "username"
transport.connect(username = username, password = password)
sftp = paramiko.SFTPClient.from_transport(transport)
def sftp_walk(remotepath):
    path=remotepath
    files=[]
    folders=[]
    for f in sftp.listdir_attr(remotepath):
        if S_ISDIR(f.st_mode):
            folders.append(f.filename)
        else:
            files.append(f.filename)
    if files:
        yield path, files
    for folder in folders:
        new_path=os.path.join(remotepath,folder)
        for x in sftp_walk(new_path):
            yield x
for path,files  in sftp_walk("." or '/remotepath/'):
    for file in files:
        #sftp.get(remote, local) line for dowloading.
        sftp.get(os.path.join(os.path.join(path,file)), '/local/path/')

Отредактировано VIRTOK (Янв. 17, 2019 23:26:56)

Офлайн

#2 Янв. 18, 2019 05:16:24

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 9730
Репутация: +  843  -
Профиль   Отправить e-mail  

Функция для рекурсивной загрузки каталога по SFTP

VIRTOK
Прошу помочь разобраться как работает функция
Обычная рекурсивная функция, ничего особенного.
Как работает:
1)
Для заданной директории получает список файлов и директорий.
2)
Если элемент списка - файл, то возвращает для него информацию.
3)
Если элемент списка - директория, то запускает саму себя для этой директории как для изначальной и возвращает информацию, полученную из подвызова.

Почитай про рекурсивные функции.
Здесь подборка моих описаний рекурсии.



Офлайн

#3 Фев. 2, 2019 08:39:44

VIRTOK
Зарегистрирован: 2017-10-23
Сообщения: 77
Репутация: +  0  -
Профиль   Отправить e-mail  

Функция для рекурсивной загрузки каталога по SFTP

Написал следующий код теперь могу скачивать 1 файл , каталог скачивать не получается.

 #Host SFTP сервера
host = "test.rebex.net"
#Port SFTP сервера
port = 22
#Имя пользователя для подключения к SFTP серверу
username = "demo"
#Пароль для подключения к SFTP серверу
password = "password"
#####################################################################
import paramiko, os
from stat import S_ISDIR
#Включаем логи
paramiko.util.log_to_file('D:\\Lessons_Python\\paramiko.log')
#Используем функцию для соединения по SSH
ssh = paramiko.SSHClient()
#Получаем ключ для подключения по SSH
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
#Устанавливаем соединение с sftp
#Используя host ,username, password
sftp_connect = ssh.connect(host, username=username,password=password)
#Открываем соединение с SFTP
sftp=ssh.open_sftp()
#####################################################################
def sftp_walk(remotepath):
    path=remotepath
    files=[]
    folders=[]
    for f in sftp.listdir_attr(remotepath):
        if S_ISDIR(f.st_mode):
            folders.append(f.filename)
        else:
            files.append(f.filename)
    if files:
        yield path, files
    for folder in folders:
        new_path=os.path.join(remotepath,folder)
        for x in sftp_walk(new_path):
            yield x
for path,files  in sftp_walk("."):
    for file in files:
        #sftp.get(remote, local) line for dowloading.
        sftp.get(os.path.join(os.path.join(path,file)), 'D:\\Lessons_Python\\readme.txt')

Отредактировано VIRTOK (Фев. 2, 2019 08:43:39)

Офлайн

#4 Фев. 4, 2019 13:49:18

uf4JaiD5
Зарегистрирован: 2018-12-28
Сообщения: 76
Репутация: +  4  -
Профиль   Отправить e-mail  

Функция для рекурсивной загрузки каталога по SFTP

Для начала

 sftp.get(os.path.join(os.path.join(path,file)), 'D:\\Lessons_Python\\readme.txt')
заменить на:
 sftp.get(os.path.join(path,file), os.path.join('D:\\Lessons_Python', file))

А потом начать разбирать path, чтоб сохранялась структура каталогов. sftp.get же сам несуществующие в ‘D:\\Lessons_Python’ каталоги не создаст?

Офлайн

#5 Фев. 8, 2019 07:15:34

VIRTOK
Зарегистрирован: 2017-10-23
Сообщения: 77
Репутация: +  0  -
Профиль   Отправить e-mail  

Функция для рекурсивной загрузки каталога по SFTP

Теперь программа работает ,но закачивает все файлы из всех папок в одну
рекурсивная загрузка каталогов не происходит.

 #Host SFTP сервера
host = "test.rebex.net"
#Port SFTP сервера
port = 22
#Имя пользователя для подключения к SFTP серверу
username = "demo"
#Пароль для подключения к SFTP серверу
password = "password"
#####################################################################
import paramiko, os
from stat import S_ISDIR
#Включаем логи
paramiko.util.log_to_file('D:\\Lessons_Python\\paramiko.log')
#Используем функцию для соединения по SSH
ssh = paramiko.SSHClient()
#Получаем ключ для подключения по SSH
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
#Устанавливаем соединение с sftp
#Используя host ,username, password
sftp_connect = ssh.connect(host, username=username,password=password)
#Открываем соединение с SFTP
sftp=ssh.open_sftp()
#####################################################################
def sftp_walk(remotepath):
    path=remotepath
    files=[]
    folders=[]
    for f in sftp.listdir_attr(remotepath):
        if S_ISDIR(f.st_mode):
            folders.append(f.filename)
        else:
            files.append(f.filename)
    if files:
        yield path, files
    for folder in folders:
        new_path=os.path.join(remotepath,folder)
        for x in sftp_walk(new_path):
            yield x
for path,files  in sftp_walk("."):
    for file in files:
        #sftp.get(remote, local) line for dowloading.
         sftp.get(os.path.join(path,file), os.path.join('D:\\Lessons_Python', file))[u][/u]

Офлайн

#6 Фев. 8, 2019 07:17:13

VIRTOK
Зарегистрирован: 2017-10-23
Сообщения: 77
Репутация: +  0  -
Профиль   Отправить e-mail  

Функция для рекурсивной загрузки каталога по SFTP

Нужно сохранять структуру каталогов и их содержимое в таком виде в котором они лежат на сервере.

Офлайн

#7 Фев. 8, 2019 10:38:04

JOHN_16
От: Россия, Петропавловск-Камчатск
Зарегистрирован: 2010-03-22
Сообщения: 3292
Репутация: +  221  -
Профиль   Отправить e-mail  

Функция для рекурсивной загрузки каталога по SFTP

одно из основных правил - не выкладывайте публично реальные ключи доступа к сереврам и/или аккаунтам.



_________________________________________________________________________________
полезный блог о python john16blog.blogspot.com

Офлайн

#8 Фев. 11, 2019 04:53:56

uf4JaiD5
Зарегистрирован: 2018-12-28
Сообщения: 76
Репутация: +  4  -
Профиль   Отправить e-mail  

Функция для рекурсивной загрузки каталога по SFTP

VIRTOK
Нужно сохранять структуру каталогов и их содержимое в таком виде в котором они лежат на сервере.
Примерно так
 #
from os.path import exists
from os import mkdir
from pathlib import Path
...
for path,files  in sftp_walk("."):
    localpath = 'D:\\Lessons_Python'
    for p in Path(path).parts:
        localpath = join(localpath, p)
        if not exists(localpath):
            mkdir(localpath)
    for file in files:
        #sftp.get(remote, local) line for dowloading.
         sftp.get(os.path.join(path,file), os.path.join(localpath, file))

Офлайн

#9 Фев. 11, 2019 19:07:31

VIRTOK
Зарегистрирован: 2017-10-23
Сообщения: 77
Репутация: +  0  -
Профиль   Отправить e-mail  

Функция для рекурсивной загрузки каталога по SFTP

JOHN_16
одно из основных правил - не выкладывайте публично реальные ключи доступа к сереврам и/или аккаунтам.
Спасибо за предупреждение ,но это публичный SFTP для тестирования,им может воспользоваться каждый. Так что все хорошо .

Офлайн

#10 Фев. 24, 2019 11:39:46

VIRTOK
Зарегистрирован: 2017-10-23
Сообщения: 77
Репутация: +  0  -
Профиль   Отправить e-mail  

Функция для рекурсивной загрузки каталога по SFTP

Нужно что бы файлы с SFTP попадали не в один каталог , а создавались точно такие же каталоги как на SFTP на локальном компьютере.

На данном этапе получаем код:

 #Host SFTP сервера
host = "test.rebex.net"
#Port SFTP сервера
port = 22
#Имя пользователя для подключения к SFTP серверу
username = "demo"
#Пароль для подключения к SFTP серверу
password = "password"
#######################################################################################################################
import paramiko, os
from stat import S_ISDIR
#Включаем логи
paramiko.util.log_to_file('D:\\Lessons_Python\\paramiko.log')
#Используем функцию для соединения по SSH
ssh = paramiko.SSHClient()
#Получаем ключ для подключения по SSH
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
#Устанавливаем соединение с sftp
#Используя host ,username, password
sftp_connect = ssh.connect(host, username=username,password=password)
#Открываем соединение с SFTP
sftp=ssh.open_sftp()
def sftp_connect():
#Включаем логи
    paramiko.util.log_to_file('D:\\Рaramiko\\paramiko.log')
#Используем функцию для соединения по SSH
    ssh = paramiko.SSHClient()
#Получаем ключ для подключения по SSH
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
#Устанавливаем соединение с sftp
#Используя host ,username, password
    sftp_connect = ssh.connect(host, username=username,password=password)
#Открываем соединение с SFTP
    sftp=ssh.open_sftp()
def sftp_walk(remotepath):
    path=remotepath
    files=[]
    folders=[]
    for f in sftp.listdir_attr(remotepath):
        if S_ISDIR(f.st_mode):
            folders.append(f.filename)
        else:
            files.append(f.filename)
    if files:
        yield path, files
    for folder in folders:
        new_path=os.path.join(remotepath,folder)
        for x in sftp_walk(new_path):
            yield x
for path,files  in sftp_walk("."):
    for file in files:
        #sftp.get(remote, local) line for dowloading.
        sftp.get(os.path.join(path,file), os.path.join('D:\\Рaramiko\\', file))
Результат
1.Файлы из всех папок на сервера SFTP загружаются в один каталог.
2. Получаем ошибку после выполнения скрипта
 C:\Users\Users\AppData\Local\Programs\Python\Python37-32\python.exe D:/Рaramiko/Рaramiko_SFTP.py
C:\Users\Users\AppData\Local\Programs\Python\Python37-32\lib\site-packages\paramiko\kex_ecdh_nist.py:39: CryptographyDeprecationWarning: encode_point has been deprecated on EllipticCurvePublicNumbers and will be removed in a future version. Please use EllipticCurvePublicKey.public_bytes to obtain both compressed and uncompressed point encoding.
  m.add_string(self.Q_C.public_numbers().encode_point())
C:\Users\Pavel\AppData\Local\Programs\Python\Python37-32\lib\site-packages\paramiko\kex_ecdh_nist.py:96: CryptographyDeprecationWarning: Support for unsafe construction of public numbers from encoded data will be removed in a future version. Please use EllipticCurvePublicKey.from_encoded_point
  self.curve, Q_S_bytes
C:\Users\Users\AppData\Local\Programs\Python\Python37-32\lib\site-packages\paramiko\kex_ecdh_nist.py:111: CryptographyDeprecationWarning: encode_point has been deprecated on EllipticCurvePublicNumbers and will be removed in a future version. Please use EllipticCurvePublicKey.public_bytes to obtain both compressed and uncompressed point encoding.
  hm.add_string(self.Q_C.public_numbers().encode_point())

Отредактировано VIRTOK (Фев. 24, 2019 12:05:34)

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version