python-ftp下载远程文件,及目录下的文件

#!/usr/bin/python
#coding=utf-8
'''
    ftp自动下载、自动上传脚本,可以递归目录操作
'''

from ftplib import FTP
import os,sys,string,datetime,time
import socket

class MYFTP: 
    def __init__(self, hostaddr, username, password, remotedir, port=21):  #初始化类
        self.hostaddr = hostaddr #IP
        self.username = username #用户名
        self.password = password #密码
        self.remotedir  = remotedir #远程文件夹
        self.port     = port #端口号
        self.ftp      = FTP() #ftp #设置变量
        self.file_list = [] #文件列表
        # self.ftp.set_debuglevel(2) #打开调试级别2,显示详细信息
    def __del__(self):
        self.ftp.close() #关闭ftp连接
        # self.ftp.set_debuglevel(0)
    def login(self):
        ftp = self.ftp  
        try: 
            timeout = 60
            socket.setdefaulttimeout(timeout)  #默认ftp连接超时时间60秒
            ftp.set_pasv(True) #下载模式 被动模式 false禁用被动
            print '开始连接到 %s' %(self.hostaddr) #打印连接信息
            ftp.connect(self.hostaddr, self.port) #连接
            print '成功连接到 %s' %(self.hostaddr) #打印连接信息
            print '开始登录到 %s' %(self.hostaddr) #打印连接信息
            ftp.login(self.username, self.password) #登录  匿名登录的话使用空串
            print '成功登录到 %s' %(self.hostaddr) #打印连接信息
            debug_print(ftp.getwelcome()) #打印出FTP欢迎信息
        except Exception:
            deal_error("连接或登录失败") #登录异常
        try:
            ftp.cwd(self.remotedir)  #设置FTP当前操作的路径为 remotedir
        except(Exception):
            deal_error('切换目录失败') #目录异常

    def is_same_size(self, localfile, remotefile):#判断本地是否有相同文件
        try:
            remotefile_size = self.ftp.size(remotefile) #远程文件大小
        except:
            remotefile_size = -1
        try:
            localfile_size = os.path.getsize(localfile)  #本地文件大小
        except:
            localfile_size = -1
        debug_print('lo:%d  re:%d' %(localfile_size, remotefile_size),)
        if remotefile_size == localfile_size:  #文件大小是否相同
             return 1
        else:
            return 0
    def download_file(self, localfile, remotefile):  #下载文件到本地
        if self.is_same_size(localfile, remotefile):  #判断本地是否有相同文件 函数is_same_size
             debug_print('%s 文件大小相同,无需下载' %localfile) #文件相同 跳过下载
             return
        else:
            debug_print('>>>>>>>>>>>>下载文件 %s ... ...' %localfile) #日志
        #return
        #下载FTP文件
        file_handler = open(localfile, 'wb')  
        self.ftp.retrbinary('RETR %s'%(remotefile), file_handler.write) 
        file_handler.close() 

    def download_files(self, localdir='./', remotedir='./'):   #下载文件
        try:
            self.ftp.cwd(remotedir) #设置FTP当前操作的路径为 remotedir
        except:
            debug_print('目录%s不存在,继续...' %remotedir)  #远程目录remotedir不存在
            return
        if not os.path.isdir(localdir): #判断本地目录是否存在
            os.makedirs(localdir) #不存在则创建
        debug_print('切换至目录 %s' %self.ftp.pwd())  #打印日志信息
        self.file_list = [] #初始化清空列表file_list 存放获取到的文件列表
        self.ftp.dir(self.get_file_list)  
        #查看目录下的所有文件 目录为get_file_list函数的返回值 详细见get_file_list函数
        #get_file_list函数会将获取到的文件信息添加到 file_list
        remotenames = self.file_list #设置变量remotenames的值为获取到的文件 以下看到遍历信息[0][1] 可知获取文件信息时返回值
        #print(remotenames)
        #return
        print remotenames #打印
        for item in remotenames:  #遍历remotenames
            filetype = item[0] #类型  文件夹还是文件
            filename = item[1] #文件名
            local = os.path.join(localdir, filename) #本地目录和文件名拼接
            if filetype == 'd':  #类型为文件夹
                self.download_files(local, filename) #递归下载  目录切换
            elif filetype == '-': #类型为文件
                self.download_file(local, filename) #下载文件到本地 下载文件具体见函数download_file
        self.ftp.cwd('..') #目录下不存在目录时候结束递归切换到上一层目录继续下载
        debug_print('返回上层目录 %s' %self.ftp.pwd())  #日志信息
        
      
'''
#上传
'''        
    def upload_file(self, localfile, remotefile): #上传文件
        if not os.path.isfile(localfile):   #本地文件不存在退出
            return
        if self.is_same_size(localfile, remotefile):  #存在相同大小文件    跳过
             debug_print('跳过[相等]: %s' %localfile) 
             return
        #FTP上传文件
        file_handler = open(localfile, 'rb')  
        self.ftp.storbinary('STOR %s' %remotefile, file_handler)
        file_handler.close()
        debug_print('已传送: %s' %localfile)#日志
    def upload_files(self, localdir='./', remotedir = './'): #上传文件
        if not os.path.isdir(localdir):  #本地目录不存在退出
            return
        localnames = os.listdir(localdir) #列出本地文件夹
        self.ftp.cwd(remotedir)  #设置远程ftp操作目录
        for item in localnames:  #遍历本地目录
            src = os.path.join(localdir, item)
            if os.path.isdir(src): #文件夹  递归
                try:
                    self.ftp.mkd(item)  #新建远程目录
                except:
                    debug_print('目录已存在 %s' %item)
                self.upload_files(src, item)
            else:
                self.upload_file(src, item) #上传文件
        self.ftp.cwd('..') #目录下不存在目录时候结束递归切换到上一层目录继续

    def get_file_list(self, line): #查看目录下的所有文件
        ret_arr = []  #初始化ret_arr
        file_arr = self.get_filename(line) #获取文件名 方法get_filename
        if file_arr[1] not in ['.', '..']:  #去掉 '.'  '..'
            self.file_list.append(file_arr) #文件信息添加到类的file_list
            
    def get_filename(self, line): #文件信息截取文件名和类型
#        pass
#'''     
#文件信息
# 权限-文件d文件夹                                                 文件或文件夹名
#    -rw-r--r--       1 0        0            1234 May 31 09:56    file.xxx
#    drwxr-xr-x       2 0        0            1234 May 31  2020    this_is_dir
#
#类型截取第一个字符串 'd' '-'   name截取最后一个空格之后的   可以rfind(' ') 或者split()  但是都不适用于文件名带空格
#若截取时间信息的  :  往后移动  适用于文件名带空格的文件   但是有些信息不全的文件时间信息只有年份 没有具体时间点 
#
    
#        此处是测试内容
#        要求:完善这个方法实现FTP递归下载
        return [line[0],line.split()[-1]]    ########此处为补全
#'''
def debug_print(s):
    print (s)
def deal_error(e):
    timenow  = time.localtime()
    datenow  = time.strftime('%Y-%m-%d', timenow)
    logstr = '%s 发生错误: %s' %(datenow, e)
    debug_print(logstr)
    file.write(logstr)
    sys.exit()

if __name__ == '__main__':
    file = open("log.txt", "a")
    timenow  = time.localtime()
    datenow  = time.strftime('%Y-%m-%d', timenow)
    logstr = datenow
    # 配置如下变量
    hostaddr = '168.7.63.172' # ftp地址
    username = 'root' # 用户名
    password = 'root1234' # 密码
    port  =  21   # 端口号 
    rootdir_local  = '/root/abc' # 本地目录
    rootdir_remote = '/etc/vsftpd'          # 远程目录
    
    f = MYFTP(hostaddr, username, password, rootdir_remote, port) #初始化类MYFTP:f
    f.login() #登录远程ftp
    f.download_files(rootdir_local, rootdir_remote)  #下载文件 参数本地路径 远程路径
    
    timenow  = time.localtime()
    datenow  = time.strftime('%Y-%m-%d', timenow)
    logstr += " - %s 成功执行了备份\n" %datenow
    debug_print(logstr)
    
    file.write(logstr)
    file.close()
 

你可能感兴趣的:(python-ftp)