網站首頁 編程語言 正文
第一章:連接 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()
② 進入指定目錄并顯示文件信息
方法 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)
這是原始目錄。
③ 區分文件和文件夾名
從上面方法 ftp.dir() 返回結果可以看到包含
def diff_dir(ftp, path): ''' 作用:區分文件和文件夾 參數1:ftp連接對象 參數2:要展示的目錄 返回:無 ''' # 進入指定目錄 ftp.cwd(path) # 顯示當前所在位置 print("當前所在位置為:") print(ftp.pwd()) # 展示目錄內容 print("\n顯示目錄內容:") dirs = [] ftp.dir(".", dirs.append) for i in dirs: # 區分文件和文件夾 if("" in i): print("目錄為:" + i.split(" ")[-1]) else: print("文件為:" + i.split(" ")[-1]) path = "/CaseData/nc.vo.sdp.testcase.testcase.TestcaseHVO/" diff_dir(ftp, path)
④ 文件夾名包含空格處理
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:52AMC2021.11_ZDHJC_004a") get_dir_name("03-08-25 10:32AM 89098 hello .exe")
⑤ 使用遞歸實現: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("" 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.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(" " 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)
可以看到符合關鍵詞的目錄被下載到本地了。
并且里面的嵌套目錄也同步被下載了。
第二章:問題解決
① 下載的文件名包含中文【‘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. 錯誤了。
原文鏈接:https://blog.csdn.net/qq_38161040/article/details/123346360
相關推薦
- 2022-09-05 內置指令、自定義指令(詳細)、全局指令與局部指令
- 2022-12-07 C++?基本數據類型中int、long等整數類型取值范圍及原理分析_C 語言
- 2023-07-31 el-tree默認展開或折疊,全選或全不選
- 2023-03-01 Shell?$[]對整數進行數學運算實現_linux shell
- 2022-06-07 SQL?Server內存機制詳解_MsSql
- 2022-03-15 has been blocked by CORS policy: Response to prefl
- 2022-07-19 react組件通訊的三種方式props:父組件和子組件互相通訊、兄弟組件通訊
- 2022-05-11 k8s創建一個簡單的Pod
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支