簡體   English   中英

使用 Python 從包含給定字符串的 FTP 服務器下載文件

[英]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)

您可以使用fsspecFTPFileSystem方便地在 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM