我试图从ftp服务器下载大量共享一个公共字符串(' DEM')的大量文件。这些文件嵌套在多个目录中。例如,' Adair> DEM *'和'亚当斯> DEM *'
FTP服务器位于此处:ftp://ftp.igsb.uiowa.edu/gis_library/counties/,不需要用户名和密码。 所以,我想浏览每个县并下载包含字符串的文件' DEM'
我已经在堆栈和python的文档中阅读了很多问题,但无法弄清楚如何使用ftplib.FTP()进入网站而没有用户名和密码(这不是必需的),以及我无法弄清楚如何在ftplib或urllib中grep或使用glob.glob。
提前感谢您的帮助
答案 0 :(得分:3)
好的,似乎有效。如果尝试下载目录或扫描文件,可能会出现问题。异常处理可以方便地捕获错误的文件类型并跳过。
由于您在远程文件系统上, 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)
fh = open(local_filename, 'wb')
fc.retrbinary('RETR '+ l + "/" + f, fh.write)
fc.close()
答案 1 :(得分:0)
具有本地模式匹配的answer by @Jean是遵循FTP标准的正确便携式解决方案。
尽管与most FTP servers do support non-standard wildcard use with file listing commands一样,您几乎总是可以使用更简单,主要是更有效的解决方案,例如:
files = ftp.nlst("*DEM*")
for f in files:
with open(f, 'wb') as fh:
ftp.retrbinary('RETR ' + f, fh.write)
答案 2 :(得分:0)
您可以使用 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*")
,但速度可能很慢。