开发者

Python实现连接FTP并下载文件夹

目录
  • 第一章:连接FTP服务器并实现文件夹下载
    • ①连接FTP服务器
    • ②进入指定目录并显示文件信息
    • ③区分文件和文件夹名
    • ④文件夹名包含空格处理
    • ⑤使用递归实现:FTP服务器里的文件夹下载到本地
  • 第二章:问题解决

    第一章:连接 FTP 服务器并实现文件夹下载

    ① 连接 FTP 服务器

    如果 FTP 不用用户名密码就直接可以访问,那就是用的默认用户名 Anonymous,密码为空。

    # -*- coding: UTF8 -*-
    # 2022-3-8
    # 作者:小蓝枣
    # python连接ftp服务器
    from ftplib import FTP
    
    def conn_ftp():
        '''
         作用:连接ftp服务器
         参数:无
         返回编程客栈:ftp服务器连接的对象
        '''
        
        # FTP连接信息
        ftp_ip = "xx.xx.xx.xx"
        # 默认端口21
        ftp_port = 21
        # 如果未指定,使用默认用户名为Anonymous,密码为空
        ftp_user = "Anonymous"
        ftp_password = ""
    
        ftp = FTP()
        # 连接ftp
        ftp.connect(ftp_ip, ftp_port)
        # ftp登录
        ftp.login(ftp_user, ftp_password)
        # 查看欢迎信息
        print(ftp.getwelcome())
        
        return ftp
        
    ftp = conn_ftp()
    

    Python实现连接FTP并下载文件夹

    ② 进入指定目录并显示文件信息

    方法 ftp.dir() 返回结果的结尾会默认带个 None,目录下没有内容的话直接会返回个 None。

    def display_dir(ftp, path):
        '''
         作用:进入并展示指定的目录内容
         参数1:ftp连接对象
         参数2:要展示的目录
         返回:无
        '''
        
        # 进入指定目录
        ftp.cwd(path)
        # 显示当前所在位置
        print("当前所在位置为:")
        print(ftp.pwd())
        # 展示目录内容
        print("\n显示目录内容:")
        print(ftp.dir())
        # 展示目录下的文件名,*文件夹和文件都会显示
        print("\n文件和文件夹名为:")
        for i in ftp.nlst():
            print(i)
    
    path = "/CaseData/nc.vo.sdp.testcase.testcase.TestcaseHVO/"
    display_dir(ftp, path)
    

    这是原始目录。

    Python实现连接FTP并下载文件夹

    Python实现连接FTP并下载文件夹

    ③ 区分文件和文件夹名

    从上面方法 ftp.dir() 返回结果可以看到包含 <DIR> 标识的为文件夹,我们根据这个特征来进行文件夹区分。

    def diff_dir(ftp, path):
        '''
         作用:区分文件和文件夹
      www.cppcns.com   参数1:ftp连接对象
         参数2:要展示的目录
         返回:无
        '''
        
        # 进入指定目录
        ftp.cwd(path)
        # 显示当前所在位置
        print("当前所在位置为:")
        print(ftp.pwd())
        # 展示目录内容
        print("\n显示目录内容:")
        dirs = []
        ftp.dir(".", dirs.append编程客栈)
        for i in dirs:
            # 区分文件和文件夹
            if("<DIR>" in i):
                print("目录为:" + i.split(" ")[-1])
            else:
                print("文件为:" + i.split(" ")[-1])
    
    path = "/CaseData/nc.vo.sdp.testcase.testcase.TestcaseHVO/"
    diff_dir(ftp, path)
    

    Python实现连接FTP并下载文件夹

    ④ 文件夹名包含空格处理

    split(" ")[-1] 方法有个缺陷,如果文件或文件夹名里包含空格,得到到的文件夹名就不对了,下面的方法可以有效的解决这个问题

    def get_dir_name(s):
        '''
         作用:需要文件或文件夹名
         参数1:需要截取的字符串
         返回:文件或文件夹名
        '''
        dir_name = ""
        k = 0
        record = ""
        for i in s:
            if(record == " " and i != " "):
                k = k + 1;
            if(k >= 3):
                dir_name = dir_name + i;
            record = i
            
        print(dir_name)
        return dir_name
    
    # 测试两条数据
    get_dir_name("03-08-22  09:52AM       <DIR>          C2021.11_ZDHJC_004a")
    get_dir_name("03-08-25  10:32AM                89098 hello .exe")
    

    Python实现连接FTP并下载文件夹

    ⑤ 使用递归实现:FTP服务器里的文件夹下载到本地

    思路:

    首先是看目录或文件里是否包含关键词,包含关键词进行下载。

    并判断是否是目录,如果是目录的话,本地根据目录结构进行递归,同时本地创建文件夹。

    使用了 2 个方法,下面的方法用来判断是否包含关键词,上面的方法就是目录结构下的递归。

    注意:由于是一个 ftp 连接对象,递归过程中进去某个目录下,递归结束要回到之前的目录。

    import pathlib
    
    def download_dir(ftp, path, local_path):
        '''
         作用: 下载目录
         参数1:ftp连接对象
         参数2:要展示的目录
         参数3:本地存放路径
         返回:无
        '''
        
        # 进入指定目录
        ftp.cwd(path)
        # 区分文件和文件夹
        dirs = []
        ftp.dir(".", dirs.append)
        for i in dirs:
            try:
                # 识别为目录进行递归
                if("<DIR>" in i):
                    dir_name = get_dihttp://www.cppcns.comr_name(i)
                    local_path_new = local_path + "/" + dir_name
                    # 本地创建文件夹
                    pathlib.Path(l编程客栈ocal_path_new).mkdir(parents=True, exist_ok=True)
                    # 调用下载目录方法
                    download_dir(ftp, dir_name, local_path_new)
                # 识别为文件进行下载
                else:
                    file_name = get_dir_name(i)
                    local_filename = local_path + "/" + file_name
                    f = open(local_filename, "wb")
                    # 下载ftp文件
                    ftp.retrbinary('RETR ' + file_name, f.write)
                    f.close()
            except Exception as e:
                print(e)
        
        # 退出当前目录
        ftp.cwd("..")
    
    def download_file(ftp, key, path, local_path):
        '''
         作用: 根据关键词下载文件
         参数1:ftp连接对象
         参数2:下载的关键词
         参数3:要展示的目录
         参数4:本地存放路径
         返回:无
        '''
        
        # 进入指定目录
        ftp.cwd(path)
        # 区分文件和文件夹
        dirs = []
        ftp.dir(".", dirs.append)
        for i in dirs:
            if(key in i):
                try:
                    # 识别为目录进行递归
                    if("<DIR>" in i):
                        dir_name = get_dir_name(i)
                        local_path_new = local_path + "/" + dir_name
                        # 本地创建文件夹
                        pathlib.Path(local_path_new).mkdir(parents=True, exist_ok=True)
                        # 调用下载目录方法
                        download_dir(ftp, dir_name, local_path_new)
                    else:
                        file_name = get_dir_name(i)
                        local_filename = local_path + "/" + file_name
                        f = open(local_filename, "wb")
                        # 下载ftp文件
                        ftp.retrbinary('RETR ' + file_name, f.write)
                        f.close()
                except Exception as e:
                    print(e)
    
    # 设置编码,解决上传的文件包含中文的问题
    ftp.encoding = 'GBK'
    key = "C2021.11_ZDHJC"
    path = "/CaseData/nc.vo.sdp.testcase.testcase.TestcaseHVO/"
    local_path = "D:/ftp下载"
    download_file(ftp, key, path, local_path)
    

    可以看到符合关键词的目录被下载到本地了。

    Python实现连接FTP并下载文件夹

    并且里面的嵌套目录也同步被下载了。

    Python实现连接FTP并下载文件夹

    第二章:问题解决

    ① 下载的文件名包含中文【‘utf-8’ codec can’t decode byte …】

    设置下 FTP 对象的编码为 GBK 即可。

    ftp.encoding = 'GBK'

    不然会报如下错误:UnicodeDecodeError: 'utf-8' codec can't decode byte 0xd7 in position 114: invalid continuation byte

    ② 指定的路径存在问题【550 The system cannot find the file specified.】

    开始我用 split(" ")[-1] 方法截取文件名,由于有的文件含有中文,截取后的文件名称不对了。

    就报了 ftplib.error_perm: 550 The system cannot find the file specified. 的错误。

    ③ 下载文件前未加RETR标识【500 Command not understood.】

    下载文件时 FTP 路径前要加个 'RETR ',不然就会报 500 错误,注意后面还跟了个空格。

    # 下载ftp文件
    ftp.retrbinary('RETR ' + file_name, f.write)
    

    不然就报 ftplib.error_perm: 500 Command not understood. 错误了。

    以上就是Python实现连接FTP并下载文件夹的详细内容,更多关于Python FTP下载文件夹的资料请关注我们其它相关文章!

    0

    上一篇:

    下一篇:

    精彩评论

    暂无评论...
    验证码 换一张
    取 消

    最新开发

    开发排行榜