使用 Python 从 FTP 下载最新文件
Downloading the most recent file from FTP with Python
我一直在尝试用 Python 编写一个函数,允许下载最近添加的文件(通过文件名中的时间戳)。
可以看到格式有一个很大的时间戳。
到目前为止,我在论坛的帮助下得到的是以下代码。
在下面的代码中,我尝试使用日期字段(实际添加到 FTP 服务器的日期)进行排序。然而,
我想调整此代码,以便我可以按文件名中的时间戳对文件进行排序。
编辑(尝试稍微清理一下代码):
def DownloadFileFromFTPServer2 (server, username, password, directory_to_file, file_to_write):
try:
f = ftplib.FTP(server)
except ((socket.error, socket.gaierror), e):
print ('cannot reach to %s' % server)
return
print ("Connected to FTP server")
try:
f.login(username, password)
except ftplib.error_perm:
print ("cannot login anonymously")
f.quit()
return
print ("Logged on to the FTP server")
try:
f.cwd(directory_to_file)
print ("Directory has been set")
except Exception as inst:
print (inst)
data = []
f.dir(data.append)
datelist = []
filelist =[]
for line in data:
print (line)
col = line.split()
datestr = ' '.join(line.split()[5:8])
date = time.strptime (datestr, '%b %d %H:%M')
datelist.append(date)
filelist.append(col[8])
combo = zip (datelist, filelist)
who = dict ( combo )
# Sort by dates and get the latest file by date....
for key in sorted(iter(who.keys()), reverse = True):
filename = who[key]
print ("File to download is %s" % filename)
try:
f.retrbinary('RETR %s' % filename, open(filename, 'wb').write)
except (ftplib.err_perm):
print ("Error: cannot read file %s" % filename)
os.unlink(filename)
else:
print ("***Downloaded*** %s " % filename)
print ("Retrieving FTP server data ......... DONE")
#VERY IMPORTANT RETURN
return
f.quit()
return 1
非常感谢任何帮助。谢谢。
编辑[已解决]:
行
date = time.strptime (datestr, '%b %d %H:%M')
应替换为:
try:
date = datetime.datetime.strptime (str(col[8]), 'S01375T-%Y-%m-%d-%H-%M-%S.csv')
except Exception as inst:
continue
try-continue 很重要,因为前两条路径行(例如“.”)和 '..' 将导致 ValuError。
获得文件名列表后,您可以简单地按文件名排序,因为命名约定是 S01375T-
YYYY-MM-DD-hh-mm.csv
这样自然会排序成date/time 命令。请注意,如果 S01375T-
部分不同,您可以在固定位置或第一个 -
.
处对名称拆分进行排序
如果不是这种情况,您可以使用 datetime.datetime.strptime
方法将文件名解析为 datetime
个实例。
当然,如果您希望真正简化事情,您可以使用 PyFileSystem FTPFS,它有多种方法可以让您将 FTP 系统视为一个缓慢的本地文件系统。
尝试使用 ftp.dir 中的 -t
选项,按日期反向排序,然后取列表中的第一个:
data = []
ftp.dir('-t',data.append)
filename = data[0]
您需要从文件名中正确提取时间戳。
您可以在第一个“-”处拆分文件名并删除文件扩展名“.csv”(f.split('-', 1)[1][:-4]
)。
然后你只需要构建用于排序的datetime obj。
from datetime import datetime
def sortByTimeStampInFile(fList):
fileDict = {datetime.strptime(f.split('-', 1)[1][:-4], '%Y-%m-%d-%H-%M-%S'): f for f in fList if f.endswith('.csv')}
return [fileDict[k] for k in sorted(fileDict.keys())]
files = ['S01375T-2016-03-01-12-00-00.csv', 'S01375T-2016-01-01-13-00-00.csv', 'S01375T-2016-04-01-13-01-00.csv']
print(sortByTimeStampInFile(files))
Returns:
['S01375T-2016-01-01-13-00-00.csv', 'S01375T-2016-03-01-12-00-00.csv', 'S01375T-2016-04-01-13-01-00.csv']
顺便说一句。只要您的时间格式是 'year-month-day-hour-min-sec',一个简单的字符串排序就可以做到:
sorted([f.split('-', 1)[1][:-4] for f in fList if f.endswith('.csv')])
>>> ['2016-01-01-13-00-00', '2016-03-01-12-00-00', '2016-04-01-13-01-00']
我一直在尝试用 Python 编写一个函数,允许下载最近添加的文件(通过文件名中的时间戳)。
可以看到格式有一个很大的时间戳。
到目前为止,我在论坛的帮助下得到的是以下代码。 在下面的代码中,我尝试使用日期字段(实际添加到 FTP 服务器的日期)进行排序。然而, 我想调整此代码,以便我可以按文件名中的时间戳对文件进行排序。
编辑(尝试稍微清理一下代码):
def DownloadFileFromFTPServer2 (server, username, password, directory_to_file, file_to_write):
try:
f = ftplib.FTP(server)
except ((socket.error, socket.gaierror), e):
print ('cannot reach to %s' % server)
return
print ("Connected to FTP server")
try:
f.login(username, password)
except ftplib.error_perm:
print ("cannot login anonymously")
f.quit()
return
print ("Logged on to the FTP server")
try:
f.cwd(directory_to_file)
print ("Directory has been set")
except Exception as inst:
print (inst)
data = []
f.dir(data.append)
datelist = []
filelist =[]
for line in data:
print (line)
col = line.split()
datestr = ' '.join(line.split()[5:8])
date = time.strptime (datestr, '%b %d %H:%M')
datelist.append(date)
filelist.append(col[8])
combo = zip (datelist, filelist)
who = dict ( combo )
# Sort by dates and get the latest file by date....
for key in sorted(iter(who.keys()), reverse = True):
filename = who[key]
print ("File to download is %s" % filename)
try:
f.retrbinary('RETR %s' % filename, open(filename, 'wb').write)
except (ftplib.err_perm):
print ("Error: cannot read file %s" % filename)
os.unlink(filename)
else:
print ("***Downloaded*** %s " % filename)
print ("Retrieving FTP server data ......... DONE")
#VERY IMPORTANT RETURN
return
f.quit()
return 1
非常感谢任何帮助。谢谢。
编辑[已解决]:
行
date = time.strptime (datestr, '%b %d %H:%M')
应替换为:
try:
date = datetime.datetime.strptime (str(col[8]), 'S01375T-%Y-%m-%d-%H-%M-%S.csv')
except Exception as inst:
continue
try-continue 很重要,因为前两条路径行(例如“.”)和 '..' 将导致 ValuError。
获得文件名列表后,您可以简单地按文件名排序,因为命名约定是 S01375T-
YYYY-MM-DD-hh-mm.csv
这样自然会排序成date/time 命令。请注意,如果 S01375T-
部分不同,您可以在固定位置或第一个 -
.
如果不是这种情况,您可以使用 datetime.datetime.strptime
方法将文件名解析为 datetime
个实例。
当然,如果您希望真正简化事情,您可以使用 PyFileSystem FTPFS,它有多种方法可以让您将 FTP 系统视为一个缓慢的本地文件系统。
尝试使用 ftp.dir 中的 -t
选项,按日期反向排序,然后取列表中的第一个:
data = []
ftp.dir('-t',data.append)
filename = data[0]
您需要从文件名中正确提取时间戳。
您可以在第一个“-”处拆分文件名并删除文件扩展名“.csv”(f.split('-', 1)[1][:-4]
)。
然后你只需要构建用于排序的datetime obj。
from datetime import datetime
def sortByTimeStampInFile(fList):
fileDict = {datetime.strptime(f.split('-', 1)[1][:-4], '%Y-%m-%d-%H-%M-%S'): f for f in fList if f.endswith('.csv')}
return [fileDict[k] for k in sorted(fileDict.keys())]
files = ['S01375T-2016-03-01-12-00-00.csv', 'S01375T-2016-01-01-13-00-00.csv', 'S01375T-2016-04-01-13-01-00.csv']
print(sortByTimeStampInFile(files))
Returns:
['S01375T-2016-01-01-13-00-00.csv', 'S01375T-2016-03-01-12-00-00.csv', 'S01375T-2016-04-01-13-01-00.csv']
顺便说一句。只要您的时间格式是 'year-month-day-hour-min-sec',一个简单的字符串排序就可以做到:
sorted([f.split('-', 1)[1][:-4] for f in fList if f.endswith('.csv')])
>>> ['2016-01-01-13-00-00', '2016-03-01-12-00-00', '2016-04-01-13-01-00']