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()


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM