zoukankan      html  css  js  c++  java
  • python 进行ftp服务器和sftp服务器连接

    1.背景。

    最近接到一个任务,需要写一个python脚本,从客户公司的服务器拉取图片存放到我们公司的sftp服务器。

    由于没头没脑,所以我采用无限遍历,将对方服务器中文件的路径原原本本的复制到我们公司的服务器。、

    后来发现对方数据量过于庞大,所以决定将路径分别存放到多个csv中,csv就充当了数据库

    然后第二个脚本是在csv里获取需要下载的图片地址将他存入sftp。

    流程图

    2.ftp

    刚开始写的是这样一个版本,后来因为运行到一半的时候,由于ftp连接断掉,脚本抛出异常停了,重头开始需要很多时间,所以后来又做了断点续传

    
    import time
    from ftplib import FTP
    import os
    import csv
    """
    1.操作日志
    2.
    """
    data_num = 1
    
    class FTP_OP(object):
        def __init__(self, host, username, password, port):
            """
            初始化ftp
            :param host: ftp主机ip
            :param username: ftp用户名
            :param password: ftp密码
            :param port:  ftp端口 (默认21)
            """
            self.host = host
            self.username = username
            self.password = password
            self.port = port
            self.csv = None
    
        def ftp_connect(self):
            """
            连接ftp
            :return:
            """
            ftp = FTP()
            ftp.set_debuglevel(0)  # 不开启调试模式
            ftp.connect(host=self.host, port=self.port)  # 连接ftp
            ftp.login(self.username, self.password)  # 登录ftp
            return ftp
        def download_file(self, dst_file_path ):
            """
            从ftp下载文件到本地
            :param dst_file_path: 本地存放路径
            :return:
            """
            ftp = self.ftp_connect()
            print(ftp.getwelcome() ) #显示登录ftp信息
            ftp.cwd("ftpstufGAP")
            for dir in ftp_file_path:
                ftp.cwd(dir)
                for file_name in ftp.nlst(ftp.pwd()):
                    self.judge_file_dir(ftp, file_name, dst_file_path)
                ftp.cwd("..")
            ftp.quit()
    
        def judge_file_dir(self,ftp,file_name,dst_file_path):
            '''
            递归便利文件
            :param ftp: 
            :param file_name: 
            :param dst_file_path: 
            :return: 
            '''
            if file_name.find(".") != -1:
                if file_name.lower().endswith(".jpg") or file_name.lower().endswith(".png"):
                    print("记录成功",file_name)
            else:
                ftp.cwd(file_name)
                for file_name in ftp.nlst(ftp.pwd()):
                    res = self.judge_file_dir(ftp,file_name,dst_file_path)
                    if not res:
                        continue
                ftp.cwd("..")
    
        def write_csv(self,ftp_file):
            '''将self.csv的数据写入data.csv文件'''
            global data_num
            ### 1万条写一个csv
            if len(self.csv)>10000:
                data_num +=1
                self.csv.clear()
                self.csv = [["Number", "FolderBane", "BarCode", "FileName"]]
    
            with open('downLoad/data/data%s.csv'%data_num, 'w',encoding="utf-8", newline='')as csv_file:
                # 获取一个csv对象进行内容写入
                writer = csv.writer(csv_file)
                for row in self.csv:
                    # writerow 写入一行数据
                    writer.writerow(row)
            return True
    
    if __name__ == "__main__":
        host = "127.0.0.1"
        username = "anonymous"
        password = ""
        port = 21
        ftp_file_path = ["2020","2019"] # 下载的文件夹子
        dst_file_path = os.getcwd()
        ftp = FTP_OP(host=host, username=username, password=password, port=port)
        start_time = time.time()
        print("记录开始")
        ftp.download_file(dst_file_path)
        between_time = time.time()
        print("记录结束,用时%.2fs"%(between_time-start_time))
    

    3.sftp 图片上传

    将本地的文件上传到sftp服务器,由于paramiko,没有提供一次行创建多层目录的功能,所以采用了一个笨办法,把目录按"/"切割成字符串

    在逐步拼接出目录,使用 sftp.listdir(sftp_path) 方法,如果抛出异常则目录不存在是用 sftp.mkdir(sftp_path)创建出这一级目录。

     class SFTP_OP(object):
        def __init__(self, host, username, password, port):
            self.host = host
            self.port = port
            self.username = username
            self.password = password
            self.set= set()
    
        def sftp_upload(self,local_list,remote):
            sf = paramiko.Transport((self.host,self.port))
            sf.connect(username = self.username,password = self.password)
            sftp = paramiko.SFTPClient.from_transport(sf)
            for local_url in local_list:
                sftp_url = os.path.join(remote,local_url.split("downLoad/")[-1])
                sftp_path_list = sftp_url.split("/")[4:-1]
                sftp_path = "/upload/pim/photobaseimages"
                for path in sftp_path_list:
                    sftp_path = sftp_path + "/" +path
                    if sftp_path in self.set:
                        continue
                    else:
                        try:
                            sftp.listdir(sftp_path)
                            self.set.add(sftp_path)
                        except Exception as e:
                            sftp.mkdir(sftp_path)
                            self.set.add(sftp_path)
                print("local_url"+local_url)
                print("sftp_url"+sftp_url)
                sftp.put(local_url,sftp_url)#上传文件
                print("上传成功",sftp_url)
            sf.close()
    
  • 相关阅读:
    springboot 基础
    spring 基础
    spring MVC 基础
    windows shell
    oracle 创建用户和视图并授权
    maven 安装本地依赖
    JAVA ssl 证书
    mybatis 递归
    MyBatis基础
    当年的毕设-cpf (一个简易的协议 fuzzer)
  • 原文地址:https://www.cnblogs.com/gongcheng-/p/12530583.html
Copyright © 2011-2022 走看看