Python實(shí)現(xiàn)連接FTP并下載文件夾
第一章:連接 FTP 服務(wù)器并實(shí)現(xiàn)文件夾下載
① 連接 FTP 服務(wù)器
如果 FTP 不用用戶(hù)名密碼就直接可以訪(fǎng)問(wèn),那就是用的默認(rèn)用戶(hù)名 Anonymous,密碼為空。
# -*- coding: UTF8 -*- # 2022-3-8 # 作者:小藍(lán)棗 # python連接ftp服務(wù)器 from ftplib import FTP def conn_ftp(): ''' 作用:連接ftp服務(wù)器 參數(shù):無(wú) 返回:ftp服務(wù)器連接的對(duì)象 ''' # FTP連接信息 ftp_ip = "xx.xx.xx.xx" # 默認(rèn)端口21 ftp_port = 21 # 如果未指定,使用默認(rèn)用戶(hù)名為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()
② 進(jìn)入指定目錄并顯示文件信息
方法 ftp.dir() 返回結(jié)果的結(jié)尾會(huì)默認(rèn)帶個(gè) None,目錄下沒(méi)有內(nèi)容的話(huà)直接會(huì)返回個(gè) None。
def display_dir(ftp, path): ''' 作用:進(jìn)入并展示指定的目錄內(nèi)容 參數(shù)1:ftp連接對(duì)象 參數(shù)2:要展示的目錄 返回:無(wú) ''' # 進(jìn)入指定目錄 ftp.cwd(path) # 顯示當(dāng)前所在位置 print("當(dāng)前所在位置為:") print(ftp.pwd()) # 展示目錄內(nèi)容 print("\n顯示目錄內(nèi)容:") print(ftp.dir()) # 展示目錄下的文件名,*文件夾和文件都會(huì)顯示 print("\n文件和文件夾名為:") for i in ftp.nlst(): print(i) path = "/CaseData/nc.vo.sdp.testcase.testcase.TestcaseHVO/" display_dir(ftp, path)
這是原始目錄。
③ 區(qū)分文件和文件夾名
從上面方法 ftp.dir() 返回結(jié)果可以看到包含 <DIR> 標(biāo)識(shí)的為文件夾,我們根據(jù)這個(gè)特征來(lái)進(jìn)行文件夾區(qū)分。
def diff_dir(ftp, path): ''' 作用:區(qū)分文件和文件夾 參數(shù)1:ftp連接對(duì)象 參數(shù)2:要展示的目錄 返回:無(wú) ''' # 進(jìn)入指定目錄 ftp.cwd(path) # 顯示當(dāng)前所在位置 print("當(dāng)前所在位置為:") print(ftp.pwd()) # 展示目錄內(nèi)容 print("\n顯示目錄內(nèi)容:") dirs = [] ftp.dir(".", dirs.append) for i in dirs: # 區(qū)分文件和文件夾 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)
④ 文件夾名包含空格處理
split(" ")[-1] 方法有個(gè)缺陷,如果文件或文件夾名里包含空格,得到到的文件夾名就不對(duì)了,下面的方法可以有效的解決這個(gè)問(wèn)題
def get_dir_name(s): ''' 作用:需要文件或文件夾名 參數(shù)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 # 測(cè)試兩條數(shù)據(jù) get_dir_name("03-08-22 09:52AM <DIR> C2021.11_ZDHJC_004a") get_dir_name("03-08-25 10:32AM 89098 hello .exe")
⑤ 使用遞歸實(shí)現(xiàn):FTP服務(wù)器里的文件夾下載到本地
思路:
首先是看目錄或文件里是否包含關(guān)鍵詞,包含關(guān)鍵詞進(jìn)行下載。
并判斷是否是目錄,如果是目錄的話(huà),本地根據(jù)目錄結(jié)構(gòu)進(jìn)行遞歸,同時(shí)本地創(chuàng)建文件夾。
使用了 2 個(gè)方法,下面的方法用來(lái)判斷是否包含關(guān)鍵詞,上面的方法就是目錄結(jié)構(gòu)下的遞歸。
注意:由于是一個(gè) ftp 連接對(duì)象,遞歸過(guò)程中進(jìn)去某個(gè)目錄下,遞歸結(jié)束要回到之前的目錄。
import pathlib def download_dir(ftp, path, local_path): ''' 作用: 下載目錄 參數(shù)1:ftp連接對(duì)象 參數(shù)2:要展示的目錄 參數(shù)3:本地存放路徑 返回:無(wú) ''' # 進(jìn)入指定目錄 ftp.cwd(path) # 區(qū)分文件和文件夾 dirs = [] ftp.dir(".", dirs.append) for i in dirs: try: # 識(shí)別為目錄進(jìn)行遞歸 if("<DIR>" in i): dir_name = get_dir_name(i) local_path_new = local_path + "/" + dir_name # 本地創(chuàng)建文件夾 pathlib.Path(local_path_new).mkdir(parents=True, exist_ok=True) # 調(diào)用下載目錄方法 download_dir(ftp, dir_name, local_path_new) # 識(shí)別為文件進(jìn)行下載 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) # 退出當(dāng)前目錄 ftp.cwd("..") def download_file(ftp, key, path, local_path): ''' 作用: 根據(jù)關(guān)鍵詞下載文件 參數(shù)1:ftp連接對(duì)象 參數(shù)2:下載的關(guān)鍵詞 參數(shù)3:要展示的目錄 參數(shù)4:本地存放路徑 返回:無(wú) ''' # 進(jìn)入指定目錄 ftp.cwd(path) # 區(qū)分文件和文件夾 dirs = [] ftp.dir(".", dirs.append) for i in dirs: if(key in i): try: # 識(shí)別為目錄進(jìn)行遞歸 if("<DIR>" in i): dir_name = get_dir_name(i) local_path_new = local_path + "/" + dir_name # 本地創(chuàng)建文件夾 pathlib.Path(local_path_new).mkdir(parents=True, exist_ok=True) # 調(diào)用下載目錄方法 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) # 設(shè)置編碼,解決上傳的文件包含中文的問(wèn)題 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)
可以看到符合關(guān)鍵詞的目錄被下載到本地了。
并且里面的嵌套目錄也同步被下載了。
第二章:?jiǎn)栴}解決
① 下載的文件名包含中文【‘utf-8’ codec can’t decode byte …】
設(shè)置下 FTP 對(duì)象的編碼為 GBK 即可。
ftp.encoding = 'GBK'
不然會(huì)報(bào)如下錯(cuò)誤:UnicodeDecodeError: 'utf-8' codec can't decode byte 0xd7 in position 114: invalid continuation byte
② 指定的路徑存在問(wèn)題【550 The system cannot find the file specified.】
開(kāi)始我用 split(" ")[-1] 方法截取文件名,由于有的文件含有中文,截取后的文件名稱(chēng)不對(duì)了。
就報(bào)了 ftplib.error_perm: 550 The system cannot find the file specified. 的錯(cuò)誤。
③ 下載文件前未加RETR標(biāo)識(shí)【500 Command not understood.】
下載文件時(shí) FTP 路徑前要加個(gè) 'RETR ',不然就會(huì)報(bào) 500 錯(cuò)誤,注意后面還跟了個(gè)空格。
# 下載ftp文件 ftp.retrbinary('RETR ' + file_name, f.write)
不然就報(bào) ftplib.error_perm: 500 Command not understood. 錯(cuò)誤了。
以上就是Python實(shí)現(xiàn)連接FTP并下載文件夾的詳細(xì)內(nèi)容,更多關(guān)于Python FTP下載文件夾的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
關(guān)于Python中object類(lèi)特殊方法的解釋
在學(xué)習(xí)Python的過(guò)程中我們會(huì)發(fā)現(xiàn)有一個(gè)類(lèi)?Object類(lèi)?,它是所有類(lèi)的父類(lèi),Object類(lèi)規(guī)定了python用于類(lèi)的內(nèi)置函數(shù),今天我們就來(lái)看看幾個(gè)常用的特殊方法吧2023-03-03numpy中的高維數(shù)組轉(zhuǎn)置實(shí)例
下面小編就為大家分享一篇numpy中的高維數(shù)組轉(zhuǎn)置實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-04-04python和flask中返回JSON數(shù)據(jù)的方法
下面小編就為大家整理了一篇python和flask中返回JSON數(shù)據(jù)的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-03-03python中pandas操作apply返回多列的實(shí)現(xiàn)
本文主要介紹了python中pandas操作apply返回多列的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-08-08Python 爬蟲(chóng)圖片簡(jiǎn)單實(shí)現(xiàn)
這篇文章主要介紹了Python 爬蟲(chóng)圖片簡(jiǎn)單實(shí)現(xiàn)的相關(guān)資料,需要的朋友可以參考下2017-06-06python神經(jīng)網(wǎng)絡(luò)facenet人臉檢測(cè)及keras實(shí)現(xiàn)
這篇文章主要為大家介紹了python神經(jīng)網(wǎng)絡(luò)facenet人臉檢測(cè)及keras實(shí)現(xiàn),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-05-05Python計(jì)算機(jī)視覺(jué)SIFT尺度不變的圖像特征變換
這篇文章主要為大家介紹了Python計(jì)算機(jī)視覺(jué)SIFT尺度不變的圖像特征變換,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-05-05Python虛擬環(huán)境的創(chuàng)建和包下載過(guò)程分析
這篇文章主要介紹了Python虛擬環(huán)境的創(chuàng)建和包下載,本文通過(guò)實(shí)例給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-06-06快速解釋如何使用pandas的inplace參數(shù)的使用
這篇文章主要介紹了快速解釋如何使用pandas的inplace參數(shù)的使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-07-07