[python小工具]定时自动更新FTP的内容到本地
在使用FTP服务器的时候,有时候需要定时将服务器上面的内容同步到本地,此时有一个脚本能够自动化的更新就再好不过了。
本文提供一种自动化同步机制
对于FTP服务器,一般使用可视化软件 filezila,这样可以比较快捷的更新文件内容,但是数据量大的时候,即使是使用filezila也不行.
python之中, 它里面自带的一个库文件 ftplib , 可以用它来连接FTP服务器。
使用filezila连接到服务器之后,基本可x看到下面这个样子,当我们点击一下‘最近修改’, 文件基本会按照时间顺序排序
这正是一个关键
因此,思路就是根据最近修改的时间来决定下载更新文件到本地
按照先广度,再深度这种思路,找到最近更新的文件,然后下载下来
上代码:
#coding:utf-8
import datetime
import random
import time
import string
import re
import sched
import os
from functools import cmp_to_key
from ftplib import FTP
ftpserveraddress = " 127.0.0.1" #目标FTP服务器网址
ftp_acc = 'username' #服务器账号
ftp_psw = 'password' #服务器密码
log_root = 'local_path' #本地存贮路径
cur_year=time.strftime("%Y",time.localtime())
#cur_mon=time.strftime("%b",time.localtime())
#cur_day=time.strftime("%d",time.localtime())
#cur_hour=time.strftime("%H",time.localtime())
#cur_min=time.strftime("%M",time.localtime())
st = sched.scheduler(time.time,time.sleep) #初始化调度器
def run_to_download(checktime):
'''
parameter:
checktime 检查最近checktime定义的时间内更新的文件
'''
currenttime=time.time()
print ("current new time is ",time.strftime("%Y-%m-%d_%H-%M-%S",time.localtime()))
ftp = FTP(ftpserveraddress)
ftp.login(ftp_acc,ftp_psw)
print (ftp.getwelcome())
update_file_lists=[]
second_update_folder_name_list=[]
#过滤符合目标时间内的文件
def first_filter(line):
'''
line 是FTP服务器上面各个文件的属性合集,类似于 在linux上输入 ls- l命令之后的内容
'''
ll=line.split()
tmp={}
if ll[8].find("-0")>-1 and ".zip" not in ll[8]:
fileinfo=ll
#fileinfo是一个list, 包含文件的这些属性['drw-rw-rw-', '1', 'user', 'group', '0', 'Aug', '8', '13:25', '.']
filetime=str(cur_year)+"-"+fileinfo[5]+"-"+fileinfo[6]+' '+fileinfo[7] #根据文件的第6,7,8项属性得到了文件更新的时间 "'2018-Aug-8 13:25'"
format_time=datetime.datetime.strptime(filetime,"%Y-%b-%d %H:%M")#组合转化文件最后修改的时间,最终将时间转为为标准计数时间
format_time=format_time.strftime("%Y%m%d%H%M")
format_time=time.strptime(format_time,"%Y%m%d%H%M")
format_time=time.mktime(format_time)
#根据当前时间减去文件更新时间,跟checktime比较,即得到最近指定时间内更新的文件
if (currenttime-format_time < int(checktime)) and len(fileinfo[8]) > 2: #十个小时内(36000的单位是秒)有文件更新的话,记录下来
tmp['update_file_name']=ll[8] #ll[8存贮着文件目录名字
tmp['file_update_time']=format_time
tmp['file_update_time_format_time']=filetime
update_file_lists.append(tmp)
ftp.retrlines("LIST",first_filter) #调用上面的过滤函数,选择出符合条件的文件或者文件夹
update_file_lists = sorted(update_file_lists,key=cmp_to_key(lambda x,y:x['file_update_time']-y['file_update_time']) ) #将最近更新的文件排序,优先下载更新时间比较久的文件
for i in update_file_lists:
print (" the folder %s modify at %s ,this file need update " % (i['update_file_name'],i['file_update_time_format_time']) )
second_update_folder_name_list.append(i['update_file_name'])
print ("current id list is ...............")
print (second_update_folder_name_list)
#进入下一级目录,基本同样的规则
for i in range(0, len(second_update_folder_name_list)):
r_log = '\\'+second_update_folder_name_list[i]
ftp.cwd(r_log)
print(r_log)
log_dir = []
def second_filter(line):
ll=line.split()
#print(ll)
fileinfo=ll #获取当前目录下的文件夹属性值
#['drw-rw-rw-', '1', 'user', 'group', '0', 'Aug', '8', '13:25', '.']
filetime=str(cur_year)+"-"+fileinfo[5]+"-"+fileinfo[6]+' '+fileinfo[7] #"'2018-Aug-8 13:25'"
format_time=datetime.datetime.strptime(filetime,"%Y-%b-%d %H:%M")#组合转化文件最后修改的时间,最终将时间转为为标准计数时间
format_time=format_time.strftime("%Y%m%d%H%M")
format_time=time.strptime(format_time,"%Y%m%d%H%M")
format_time=time.mktime(format_time)
#print("check time is ", checktime )
if (currenttime-format_time < int(checktime)) and len(fileinfo[8]) > 2: #十个小时内(36000的单位是秒)有文件更新的话,记录下来
log_dir.append(ll[8]) #ll[8存贮着文件目录名字]
ftp.retrlines("LIST",second_filter)
print(log_dir)
for i in range(0, len(log_dir)):
record_log = "/" + r_log.strip('\\') + "/" + log_dir[i] +"/"
#print ("log_dir is %s"%log_dir[i])
print ("log_dir %s has update"%record_log)
loglist = ftp.nlst(record_log)
print ("loglist is %s"%loglist)
ftp.cwd(record_log)
#print("pwd is %s"%ftp.pwd())
for log in loglist:
log_path = log_root + record_log
#print (log_path)
if not os.path.exists(log_path): #判断本地目录是否存在,没有就重新创建
os.makedirs(log_path)
#xxx = log_root + "/" + log # dir is ../log
xxx = log_path + log # dir is ../log-123456
if os.path.exists(xxx): #因为没有对log文件进行时间排序,因此会出现这个文件夹持续更新的情况,所以加上一层判断,如果文件已经存在,不用再次更新
#print("%s is exists, do not need update again" % xxx)
pass
else:
fp = open(xxx,'wb')
ftp.retrbinary('RETR '+log,fp.write)
fp.close()
print ("log %s didn't exists , is updating now ..." % log)
print ("........before clear , the id list , id _lists is..........")
print (update_file_lists)
print (second_update_folder_name_list)
update_file_lists.clear()
second_update_folder_name_list.clear()
print("after clear , the id list , id _lists, and log_dir is : ")
print (update_file_lists)
print (second_update_folder_name_list)
print("---------------------------finished-----------------------------------------")
st.enter(60,1,run_to_download,(360,)) #360 is the checktime
if __name__ == '__main__':
st.enter(1,1,run_to_download,(360,)) #360 is the checktime
st.run()
收获主要是,python3上面的排序方法, sort函数中的cmp函数不用了, 这里用了新的方法
另外,ftp服务器中,获取文件更新时间的方法比较特别