[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服务器中,获取文件更新时间的方法比较特别

 

posted @ 2018-08-31 15:49  枫奇丶宛南  阅读(324)  评论(0编辑  收藏  举报