zoukankan      html  css  js  c++  java
  • py实现ftp

     https://www.cnblogs.com/wangziyi0513/p/11077323.html 

    参考原始代码:

    修改了一下:

     许多网友问中文路径乱码怎么办,我觉得应该讲中文路径转码后再发送。

    ftpath = '/home/omcr/文档/{}'.format(y).encode('utf-8').decode('latin-1')


    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    # @Time    : 2019/4/12 22:00
    # @Author  : zengsk in HoHai
    # edited by wh
    '''
    FTP批量下载数据
    '''
    import os
    import sys
    from ftplib import FTP
    import datetime
    
    class FtpDownloadCls:
        def __init__(self, ftpserver, port, usrname, pwd, encode1, decode1):
            self.ftpserver = ftpserver # ftp主机IP
            self.port = port          # ftp端口
            self.usrname = usrname  # 登陆用户名
            self.pwd = pwd          # 登陆密码
            self.ftp = self.ftpConnect()
            # 用于中文编码解码,
            self.encode1 = encode1
            self.decode1 = decode1
    
        # ftp连接
        def ftpConnect(self):
            ftp = FTP()
            try:
                ftp.connect(self.ftpserver, self.port)
                ftp.login(self.usrname, self.pwd)
           # python ftplib 默认的编码方式是latin-1
                self.encode1 = ftp.encoding
            except:
                raise IOError('
     FTP login failed!!!')
            else:
                print(ftp.getwelcome())
                print('
    +------- FTP connection successful!!! --------+
    ')
                return ftp
    
        # 单个文件下载到本地
        def downloadFile(self, ftpfile, localfile):
            bufsize = 1024
         # 要在本地正确的显示中文,需要先通过latin-1编码成unicode,在解码成utf-8或GBK
            with open(localfile.encode(self.encode1).decode(self.decode1), 'wb') as fid:
                self.ftp.retrbinary('RETR {0}'.format(ftpfile), fid.write, bufsize)
            return True
    
        # 下载整个目录下的文件,包括子目录文件
        def downloadFiles(self, ftpath, localpath):
            print('FTP PATH: {0}'.format(ftpath))
            if not os.path.exists(localpath):
                os.makedirs(localpath)
            self.ftp.cwd(ftpath)
            print('
    +----------- downloading!!! -----------+
    ')
            for i, file in enumerate(self.ftp.nlst()):
                print('{0} <> {1}'.format(i, file))
                local = os.path.join(localpath, file)
                if os.path.isdir(file): # 判断是否为子目录
                    if not os.path.exists(local):
                        os.makedirs(local)
                    self.downloadFiles(file, local)
                else:
                    self.downloadFile(file, local)
            self.ftp.cwd('..')
            return True
    
        # 退出FTP连接
        def ftpDisConnect(self):
            self.ftp.quit()
    
    # 程序入口
    if __name__ == '__main__':
    
        yesterday = (datetime.datetime.now() - datetime.timedelta(days = 1))
        y = yesterday.strftime("%Y%m%d")
        # 输入参数
        ftpserver = '10.20.20.1' # ftp主机IP
        port = 21                                  # ftp端口
        usrname = 'omcr'       # 登陆用户名
        pwd = 'abcd.1'       # 登陆密码
        #ftpath = '/export/home/omcr/UMS8800_WKM_TDL_V3.0.0_26_20171013/LTE_WKM/webapps/WKMService/reportfile/计划报表/20190623/'  # 远程文件夹
        # 想要将路径中的中文正确发送到ftp服务器,需要先通过本地编码utf-8转换为unicode,在编码为latin-1,这样才能被ftplib模块正确发送给ftp服务器,虽然发送过去的中文编码是乱的
        # 但服务器可以识别
        ftpath = '/home/omcr/文档/{}'.format(y).encode('utf-8').decode('latin-1')
        localpath = 'D:/EC/data/{}'.format(y)                # 本地文件夹(不要使用中文)
    
        Ftp = FtpDownloadCls(ftpserver, port, usrname, pwd, 'latin-1', 'utf-8')
        Ftp.downloadFiles(ftpath, localpath)
        Ftp.ftpDisConnect()
        print("
    +-------- OK!!! --------+
    ")
    
        # 删除多余文件
        dirPath = r'D:/EC/data'
        x = ''
        for f in os.listdir(dirPath):
        if not x in f:
            os.remove(os.path.join(dirPath, f))
    

      实际使用脚本时,遇到几个问题:

    1、没有遵守python语法,没有严格按空4个格的要求编写脚本,导致程序运行失败。

    2、路径配置错误,solaris服务器路径从/export/home/......开始,linux服务器从/home/......开始,如果不注意,容易搞混。

    3、服务器有两种中文编码:GBK和utf-8,容易搞混。

     

    如果现场不会用cmd,则需要编写一个bat:

    py ftpdown_weekendn.py
    
    pause

    放在py脚本同一目录下,双击bat脚本执行后,cmd窗口会停在最后报错的地方。

    第二版:

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    # @Time    : 2019/4/12 22:00
    # @Author  : zengsk in HoHai
    # edited by wh
    
    '''
    FTP批量下载数据
    '''
    import os
    import sys
    from ftplib import FTP
    import datetime
    
    class FtpDownloadCls:
        def __init__(self, ftpserver, usrname, pwd, decode1, port=21, encode1='latin-1'):
            self.ftpserver = ftpserver # ftp主机IP
            self.port = port          # ftp端口
            self.usrname = usrname  # 登陆用户名
            self.pwd = pwd          # 登陆密码
            self.ftp = self.ftpConnect()
            # latin-1
            self.encode1 = encode1
            # 中文编码UTF-8或GBK
            self.decode1 = decode1
    
        # ftp连接
        def ftpConnect(self):
            ftp = FTP()
            try:
                ftp.connect(self.ftpserver, self.port, 30)
                ftp.login(self.usrname, self.pwd)
                self.encode1 = ftp.encoding
            except:
                raise IOError('
     FTP login failed!!!')
            else:
                print(ftp.getwelcome())
                print('
    +------- FTP connection successful!!! --------+
    ')
                return ftp
    
        # 单个文件下载到本地
        def downloadFile(self, ftpfile, localfile):
            bufsize = 1024
            with open(localfile, 'wb') as fid:
                self.ftp.retrbinary('RETR {0}'.format(ftpfile), fid.write, bufsize)
            return True
    
        # 下载整个目录下的文件,包括子目录文件
        def downloadFiles(self, ftpath, localpath, save='', delete='', saveset=set(), deleteset=set()):
            ftppath_t = ftpath.encode(self.decode1).decode(self.encode1)
            print('FTP PATH: {0}'.format(ftpath))
            if not os.path.exists(localpath):
                os.makedirs(localpath)
            self.ftp.cwd(ftppath_t)
            print('
    +----------- downloading!!! -----------+
    ')
            flist = set()
            for i, file in enumerate(self.ftp.nlst()):
                filename = file.encode(self.encode1).decode(self.decode1)
                if save in filename and (delete not in filename or delete is ''):
                    flist.add(filename)
            if saveset:
                flist = flist.intersection(saveset)
            flist = flist.difference(deleteset)
            for i, f in enumerate(flist):
                file = f.encode(self.decode1).decode(self.encode1)
                print('{0} <> {1}'.format(i, f))
                local = os.path.join(localpath, f)
                self.downloadFile(file, local)
            self.ftp.cwd('..')
            return True
    
        # 退出FTP连接
        def ftpDisConnect(self):
            self.ftp.quit()
    
    # 程序入口
    if __name__ == '__main__':
    
        # 取前三天或者前N天的日期
        datelist = [(datetime.datetime.now() - datetime.timedelta(days = x)) for x in range(1,4)]
    
        # 输入参数
        # 服务器中文编码方式,不是UTF-8就是GBK
        s_code = 'GBK'
        ftpserver = '10.9.0.25' # ftp主机IP
        usrname = 'root'       # 登陆用户名
        pwd = 'aapswd'       # 登陆密码
    
        Ftp = FtpDownloadCls(ftpserver, usrname, pwd, s_code)
    
        for d in datelist:
            # 小北向目录格式20190703
            y = d.strftime("%Y%m%d")
            ftppath1 = '/export/home/omcr/UMS_WKM_LTE-35/LTE_WKM/webapps/WKMService/reportfile/计划报表/{}/ENB/小时报表'.format(y)
            ftppath2 = '/export/home/omcr/UMS_WKM_LTE-35/LTE_WKM/webapps/WKMService/reportfile/计划报表/{}/ENB/天报表'.format(y)
            # 本地文件夹(不要使用中文)
            localpath = r'D:/EC/EC_XBX/{}/'.format(y)
            # 新增核对本地文件夹功能,有时ftp传输不稳定,没有传完就掉线了,需要二次执行脚本,这时本地路径下已有的文件就可以过滤出去,不必再次下载。
            if os.path.exists(localpath):
                existfiles = set(os.listdir(localpath))
            else:
                existfiles = set()
            # downloadFiles(a,b,c,d,e,f)第3个参数是过滤后留下的,第4个参数是过滤掉的
            Ftp.downloadFiles(ftppath1, localpath, '', '', deleteset=existfiles)
            Ftp.downloadFiles(ftppath2, localpath, '', '', deleteset=existfiles)
    
        Ftp.ftpDisConnect()
        print("
    +-------- OK!!! --------+
    ")
        
        # 第2组参数
        # 服务器中文编码方式,不是UTF-8就是GBK
        s_code = 'GBK'
        ftpserver = '10.2.0.12' # ftp主机IP
        usrname = 'root'       # 登陆用户名
        pwd = 'root1234'       # 登陆密码
    
        Ftp = FtpDownloadCls(ftpserver, usrname, pwd, s_code)
    
        for d in datelist:
            # OMC日期格式2019-07-02
            y_m_d = d.strftime("%Y-%m-%d")
            # 本地路径格式统一为20190703
            y = d.strftime("%Y%m%d")
            ftppath1 = '/export/home/omcrftp/pm/reports/{}'.format(y_m_d)
            # 本地文件夹(不要使用中文)
            localpath = r'D:/EC/EC_OMC/{}'.format(y)
            if os.path.exists(localpath):
                existfiles = set(os.listdir(localpath))
            else:
                existfiles = set()
            # downloadFiles(a,b,c,d,e,f)第3个参数是过滤后留下的,第4个参数是过滤掉的
            Ftp.downloadFiles(ftppath1, localpath, '级_', '', deleteset=existfiles)
    
        Ftp.ftpDisConnect()
        print("
    +-------- OK!!! --------+
    ")
    

      

    安装python环境时,经常有win7老电脑(32bit)报错如下:

     

    解决办法:

    https://www.cnblogs.com/du-hong/p/10247997.html

    api-ms-win-crt-process-l1-1-0.dll 丢失是因为缺少下边两个安装包

    KB2999226、KB3118401更新下载:

    KB2999226 微软下载链接 https://support.microsoft.com/en-us/help/2999226/update-for-universal-c-runtime-in-windows

     

    FTP登录超时:

    修改31行:ftp.connect(self.ftpserver, self.port, 30),增加, 30参数

     

    https://docs.python.org/3/library/ftplib.html#ftplib.FTP.connect

  • 相关阅读:
    递归 迷宫问题
    中缀表达式转后缀表达式
    栈实现后缀表达式计算

    单向环形链表
    站在巨人的肩上
    C#自宿主API,不依赖IIS
    MySQL 安装失败解决办法
    第一话
    村上春树《眠》读书笔记
  • 原文地址:https://www.cnblogs.com/wangziyi0513/p/11077323.html
Copyright © 2011-2022 走看看