[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服務器中,獲取文件更新時間的方法比較特別

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章