Python 使用SFTP和FTP实现对服务器的文件下载

一、用 ftplib 模块连接远程服务器:

ftplib模块常用方法

ftp登陆连接
from ftplib import FTP            #加载ftp模块
ftp=FTP()                         #设置变量
ftp.set_debuglevel(2)             #打开调试级别2,显示详细信息
ftp.connect("IP","port")          #连接的ftp sever和端口
ftp.login("user","password")      #连接的用户名,密码
print ftp.getwelcome()            #打印出欢迎信息
ftp.cmd("xxx/xxx")                #进入远程目录
bufsize=1024                      #设置的缓冲区大小
filename="filename.txt"           #需要下载的文件
file_handle=open(filename,"wb").write #以写模式在本地打开文件
ftp.retrbinaly("RETR filename.txt",file_handle,bufsize) #接收服务器上文件并写入本地文件
ftp.set_debuglevel(0)             #关闭调试模式
ftp.quit()                        #退出ftp
 
ftp相关命令操作
ftp.cwd(pathname)                 #设置FTP当前操作的路径
ftp.dir()                         #显示目录下所有目录信息
ftp.nlst()                        #获取目录下的文件
ftp.mkd(pathname)                 #新建远程目录
ftp.pwd()                         #返回当前所在位置
ftp.rmd(dirname)                  #删除远程目录
ftp.delete(filename)              #删除远程文件
ftp.rename(fromname, toname)#将fromname修改名称为toname。
ftp.storbinaly("STOR filename.txt",file_handel,bufsize)  #上传目标文件
ftp.retrbinary("RETR filename.txt",file_handel,bufsize)  #下载FTP文件

ftplib模块封装调用

from ftplib import FTP
from common.logModule import LogClass


class FTPClass(LogClass):
    """
    :FTP连接远程服务器下载文件
    """

    def __init__(self, ftp_link, ftp_path=None):
        """
        :连接ftp服务器
        :param ftp_link: 服务器ip, 用户名, 密码
        :param ftp_path: ftp中的文件路径
        """
        LogClass.__init__(self, logName='FTPClass')
        self.ftp = FTP(ftp_link[0])  # 链接FTP
        self.ftp.set_debuglevel(2)  # 设置调试等级
        self.ftp.login(ftp_link[1], ftp_link[2])  # 输入用户名和密码
        self.ftp.set_pasv(False)  # False:主动模式   True:被动模式
        if ftp_path:
            self.ftp.cwd(ftp_path)

    def download_file(self, like_file_name, save_path, save_name=None):
        """
        :下载文件并保存文件到本地,如果save_name为空则下载所有文件名称包含like_file_name的所有文件
        :param like_file_name:  需要下载的文件
        :param save_path : 文件保存路径
        :param save_name: 文件保存名称
        :return:
        """
        try:
            ftp_files = self.ftp.nlst()  # 获取ftp当前目录下的所有文件名称
            if save_name:  # 如果文件保存名称存在则只下载单一文件
                fp = open(save_path + save_name, 'wb')  # 以写模式在本地打开文件
                self.ftp.retrbinary('RETR ' + 'ftp文件名', fp.write)  # 接收服务器上文件并写入本地文件
                fp.close()  # 关闭文件
            else:  # 如果文件保存名称则下载包含like_file_name的所有文件
                for ftp_file in ftp_files:
                    if ftp_file[-5:] == '.GRB2':
                        if like_file_name in ftp_file:  # 如果文件名称中包含like_file_name
                            fp = open(save_path + ftp_file, 'wb')  # 以写模式在本地打开文件
                            self.ftp.retrbinary('RETR ' + ftp_file, fp.write)  # 接收服务器上文件并写入本地文件
                            fp.close()  # 关闭文件
            self.ftp.quit()  # 关闭ftp 连接
        except Exception:
            raise


if __name__ == '__main__':
    ftp_link = ['ip', 'username', 'password']
    ftp_path = '/data/result/'
    ftp = FTPClass(ftp_link, ftp_path)
    like_file_name = ".GRB2"
    save_path = 'D:\\file\\'
    ftp.download_file(like_file_name, save_path)

用 paramiko 模块连接远程服务器

paramiko 模块常用方法

put(self,localpath,remotepath,callback=None,confirm=True)
	参数说明:
		localpath:上传源文件的本地路径
		remotepath:目标路径
		callback:获取接收与总传输字节数
		confirm:上传完毕后是否调用stat()方法,以便确认文件大小
get(self, remotepath, localpath, callback=None)
	参数说明:
		remotepath:需要下载的远程文件
		localpath:本地存储路径
		callback:同put方法
mkdir:用于创建目录
remove:删除目录
rename:重命名
stat:获取文件信息
listdir:获取目录列表

paramiko模块封装调用

import os
import paramiko
from stat import S_ISDIR
from common.logModule import LogClass


class SFTPClass(LogClass):
    """
    :SFTP连接远程服务器下载文件
    """

    def __init__(self, ftp_link, ftp_path=None, local_path=None):
        """
        连接ftp服务器
        """
        LogClass.__init__(self, logName='FTPProcess')
        trans = paramiko.Transport((ftp_link[0], 22))  # 连接 ftp
        trans.connect(username=ftp_link[1], password=ftp_link[2])  # 输入用户名和密码
        self.sftp = paramiko.SFTPClient.from_transport(trans)
        self.ftp_path = ftp_path  # 目标路径
        self.local_path = local_path  # 保存路径

    def save_all_file_path(self, ftp_path):
        """保存所有文件的列表"""
        all_files = list()
        if ftp_path[-1] == '/':  # 去掉路径字符串最后的字符'/',如果有的话
            ftp_path = ftp_path[0:-1]
        files = self.sftp.listdir_attr(ftp_path)  # 获取当前指定目录下的所有目录及文件,包含属性值
        for i in files:
            filename = ftp_path + '/' + i.filename
            if S_ISDIR(i.st_mode):  # 如果是目录,则递归处理该目录,这里用到了stat库中的S_ISDIR方法
                all_files.extend(self.save_all_file_path(filename))
            else:
                all_files.append(filename)
        return all_files

    def download_file(self):
        """
        下载文件并保存文件到本地
        """
        try:
            if self.ftp_path and self.local_path:
                all_files = self.save_all_file_path(self.ftp_path)  # 保存所有文件的列表
                for file in all_files:
                    filename = file.split('/')[-1]
                    local_filename = os.path.join(self.local_path, filename)
                    self.logger.info(u'During file download: %s' % filename)
                    self.sftp.get(file, local_filename)  # 下载到本地
            else:
                self.logger.error("ftp_path or local_path is null")
                return
        except Exception as e:
            self.logger.error(e)


if __name__ == '__main__':
    ftp_link = ['ip', 'user', 'password']
    ftp_path = "/data/"
    local_path = "D:\\file\\"
    f = SFTPClass(ftp_link, ftp_path=None, local_path=None)
    f.download_file()

你可能感兴趣的:(Python,python)