如何用Python脚本删除FTP服务器上超过7天的文件?
我想写一个Python脚本,让我可以在FTP服务器上删除一些文件,前提是这些文件已经存在了一段时间。我准备了下面的脚本,但它出现了一个错误信息:WindowsError: [Error 3] 系统找不到指定的路径: '/test123/*.*'
有没有人知道怎么解决这个问题?谢谢大家!
import os, time
from ftplib import FTP
ftp = FTP('127.0.0.1')
print "Automated FTP Maintainance"
print 'Logging in.'
ftp.login('admin', 'admin')
# This is the directory that we want to go to
path = 'test123'
print 'Changing to:' + path
ftp.cwd(path)
files = ftp.retrlines('LIST')
print 'List of Files:' + files
#--everything works fine until here!...
#--The Logic which shall delete the files after the are 7 days old--
now = time.time()
for f in os.listdir(path):
if os.stat(f).st_mtime < now - 7 * 86400:
if os.path.isfile(f):
os.remove(os.path.join(path, f))
except:
exit ("Cannot delete files")
print 'Closing FTP connection'
ftp.close()
5 个回答
2
好的,既然不打算进一步分析你发的代码,那我给你一个例子,可能会让你更接近你想要的结果。
from ftplib import FTP
import re
pattern = r'.* ([A-Z|a-z].. .. .....) (.*)'
def callback(line):
found = re.match(pattern, line)
if (found is not None):
print found.groups()
ftp = FTP('myserver.wherever.com')
ftp.login('elvis','presley')
ftp.cwd('testing123')
ftp.retrlines('LIST',callback)
ftp.close()
del ftp
运行这个代码,你会得到类似这样的输出,这应该是你想要实现的目标的一个起点。接下来,你需要把第一个结果解析成一个日期时间格式,然后和“现在”进行比较,如果这个文件太旧,就用ftp.delete()来删除远程文件。
>>>
('May 16 13:47', 'Thumbs.db')
('Feb 16 17:47', 'docs')
('Feb 23 2007', 'marvin')
('May 08 2009', 'notes')
('Aug 04 2009', 'other')
('Feb 11 18:24', 'ppp.xml')
('Jan 20 2010', 'reports')
('Oct 10 2005', 'transition')
>>>
4
我之前也遇到过这个问题,花了不少时间,觉得可以帮大家节省一些时间。我们使用的是Python,并且安装了ftputil模块:
#! /usr/bin/python
import time
import ftputil
host = ftputil.FTPHost('ftphost.com', 'username', 'password')
mypath = 'ftp_dir'
now = time.time()
host.chdir(mypath)
names = host.listdir(host.curdir)
for name in names:
if host.path.getmtime(name) < (now - (7 * 86400)):
if host.path.isfile(name):
host.remove(name)
print 'Closing FTP connection'
host.close()
10
好的。假设你的FTP服务器支持MLSD
这个命令,你可以创建一个模块,里面写上以下代码(这是我用来同步远程FTP网站和本地目录的脚本代码):
模块代码
# for python ≥ 2.6
import sys, os, time, ftplib
import collections
FTPDir= collections.namedtuple("FTPDir", "name size mtime tree")
FTPFile= collections.namedtuple("FTPFile", "name size mtime")
class FTPDirectory(object):
def __init__(self, path='.'):
self.dirs= []
self.files= []
self.path= path
def getdata(self, ftpobj):
ftpobj.retrlines('MLSD', self.addline)
def addline(self, line):
data, _, name= line.partition('; ')
fields= data.split(';')
for field in fields:
field_name, _, field_value= field.partition('=')
if field_name == 'type':
target= self.dirs if field_value == 'dir' else self.files
elif field_name in ('sizd', 'size'):
size= int(field_value)
elif field_name == 'modify':
mtime= time.mktime(time.strptime(field_value, "%Y%m%d%H%M%S"))
if target is self.files:
target.append(FTPFile(name, size, mtime))
else:
target.append(FTPDir(name, size, mtime, self.__class__(os.path.join(self.path, name))))
def walk(self):
for ftpfile in self.files:
yield self.path, ftpfile
for ftpdir in self.dirs:
for path, ftpfile in ftpdir.tree.walk():
yield path, ftpfile
class FTPTree(FTPDirectory):
def getdata(self, ftpobj):
super(FTPTree, self).getdata(ftpobj)
for dirname in self.dirs:
ftpobj.cwd(dirname.name)
dirname.tree.getdata(ftpobj)
ftpobj.cwd('..')
单个目录的情况
如果你想处理一个目录里的文件,你可以这样做:
import ftplib, time
quite_old= time.time() - 7*86400 # seven days
site= ftplib.FTP(hostname, username, password)
site.cwd(the_directory_to_work_on) # if it's '.', you can skip this line
folder= FTPDirectory()
folder.getdata(site) # get the filenames
for path, ftpfile in folder.walk():
if ftpfile.mtime < quite_old:
site.delete(ftpfile.name)
这样应该能满足你的需求。
一个目录及其子目录
如果你想让这个功能递归工作,你需要在“单个目录的情况”中做以下两个修改:
folder= FTPTree()
还有
site.delete(os.path.join(path, ftpfile.name))
可能的注意事项
我用过的服务器在STOR
和DELE
命令中对相对路径没有问题,所以site.delete
使用相对路径也能正常工作。如果你的FTP服务器要求文件名不能带路径,你应该先用.cwd
切换到提供的path
,然后用.delete
删除简单的ftpfile.name
,最后再用.cwd
切换回基础文件夹。