[英]Download files from an FTP server containing given string using Python
我正在嘗試從 FTP 服務器下載大量共享一個公共字符串 ( DEM
) 的文件。 這些文件嵌套在多個目錄中。 例如, Adair/DEM*
和Adams/DEM*
FTP 服務器位於: ftp://ftp.igsb.uiowa.edu/gis_library/counties/
: ftp://ftp.igsb.uiowa.edu/gis_library/counties/
,不需要用戶名和密碼。 所以,我想遍歷每個縣並下載包含字符串DEM
的文件。
我在 Stack Overflow 和 Python 文檔中閱讀了很多問題,但無法弄清楚如何使用ftplib.FTP()
在沒有用戶名和密碼的情況下進入站點(這不是必需的),我不能弄清楚如何在 ftplib 或 urllib 中 grep 或使用glob.glob
。
預先感謝您的幫助
好吧,似乎工作。 如果嘗試下載目錄或掃描文件,可能會出現問題。 異常處理可能會派上用場來捕獲錯誤的文件類型並跳過。
glob.glob
無法工作,因為您在遠程文件系統上,但您可以使用fnmatch
來匹配名稱
這是代碼:它下載 TEMP 目錄中與*DEM*
匹配的所有文件,按目錄排序。
import ftplib,sys,fnmatch,os
output_root = os.getenv("TEMP")
fc = ftplib.FTP("ftp.igsb.uiowa.edu")
fc.login()
fc.cwd("/gis_library/counties")
root_dirs = fc.nlst()
for l in root_dirs:
sys.stderr.write(l + " ...\n")
#print(fc.size(l))
dir_files = fc.nlst(l)
local_dir = os.path.join(output_root,l)
if not os.path.exists(local_dir):
os.mkdir(local_dir)
for f in dir_files:
if fnmatch.fnmatch(f,"*DEM*"): # cannot use glob.glob
sys.stderr.write("downloading "+l+"/"+f+" ...\n")
local_filename = os.path.join(local_dir,f)
with open(local_filename, 'wb') as fh:
fc.retrbinary('RETR '+ l + "/" + f, fh.write)
fc.close()
@Jean使用本地模式匹配的答案是符合 FTP 標准的正確便攜式解決方案。
盡管大多數 FTP 服務器確實支持使用文件列表命令的非標准通配符,但您幾乎總是可以使用更簡單且主要更有效的解決方案,例如:
files = ftp.nlst("*DEM*")
for f in files:
with open(f, 'wb') as fh:
ftp.retrbinary('RETR ' + f, fh.write)
您可以使用fsspec
的FTPFileSystem
方便地在 FTP 服務器上進行通配:
import fsspec.implementations.ftp
ftpfs = fsspec.implementations.ftp.FTPFileSystem("ftp.ncdc.noaa.gov")
files = ftpfs.glob("/pub/data/swdi/stormevents/csvfiles/*1985*")
print(files)
contents = ftpfs.cat(files[0])
print(contents[:100])
結果:
['/pub/data/swdi/stormevents/csvfiles/StormEvents_details-ftp_v1.0_d1985_c20160223.csv.gz', '/pub/data/swdi/stormevents/csvfiles/StormEvents_fatalities-ftp_v1.0_d1985_c20160223.csv.gz', '/pub/data/swdi/stormevents/csvfiles/StormEvents_locations-ftp_v1.0_d1985_c20160223.csv.gz']
b'\x1f\x8b\x08\x08\xcb\xd8\xccV\x00\x03StormEvents_details-ftp_v1.0_d1985_c20160223.csv\x00\xd4\xfd[\x93\x1c;r\xe7\x8b\xbe\x9fOA\xe3\xd39f\xb1h\x81[\\\xf8\x16U\x95\xac\xca\xc5\xacL*3\x8b\xd5\xd4\x8bL\xd2\xb4\x9d'
嵌套搜索也有效,例如, nested_files = ftpfs.glob("/pub/data/swdi/stormevents/**1985*")
,但它可能很慢。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.