用Python写一个ftp下载脚本
----基于Red Hat Enterprise Linux Server release 6.4 (Santiago);python 2.6.6
Ps:少侠我接触Python半个月以来接到的第一个需求,虽然如此简单的一个脚本,少侠我磕磕绊绊却用了将近一天半的时间才写出来,但还是很开心,毕竟也粗来了,废话不多说,切入正题。因为一开始没有用过ftplib模块,所以各种谷歌度娘一堆资料杂乱不堪,话不清,理不乱的,本文实现的功能简单,下面介绍一下,以免误导读者。
需求:师傅给了一个需求,写一个ftp自动下载的脚本。似乎下载文件没什么难的,用ftp下载文件似乎更简单,get,mget完事。但是需求是,服务器上主要是dat文件在备份,当备份完成后,会生成一个同名字的ack文件,要把备份完成的dat文件下载到本地,然后删除云端服务器的ack和dat文件。虽然听着这个需求挺找抽,也挺容易实现的,但谁叫我是菜鸟呢,当时就蒙圈了。
ftp地址192.168.213.129
用户名dmp
密码zcxc123!
文件位置/var/ftp/pub/pizi
我看了下大概3分钟生成一个文件,文件忙时可能要60M以上,网管网估计悬,师父让我先写脚本,回头联系拉内网走。吐槽完毕,开始上干货:
----------------------------------------------分隔线---------------------------------------------
下面正式切入正题:
1. 首先要引入ftplib模块,Python中默认安装的ftplib模块定义了FTP类,其中函数有限,可用来实现简单的ftp客户端,用于上传或下载文件。网上有很多远程登录的实例,下面写一种最适合菜鸟的写法
2. 基本的代码如下:
from ftplib import FTP
###引入ftp模块
import re
###引入re模块使Python拥有全部的正则表达式的功能
ftp = FTP(‘目的主机的ip地址’)
####连接ftp服务器
ftp.login(‘user’,’passwd’)
###登录ftp服务器
ftp.cwd(‘ftp存放文件的路径’)
###设置一个你要登录的目录,下载上传文件都在此目录
ftp.nlst()
###获取目录下的文件
file_handle=open(filename,"wb").write
###以写模式在本地打开文件
ftp.retrbinary("RETR filename.txt",file_handel,bufsize)
###下载ftp文件
ftp.delete(filename)
###删除ftp服务器上的文件
3. 下面粘上我的代码
#!/usr/bin/python
#coding=utf-8
import re
import os
from ftplib import FTP
os.chdir('更改的当前目录,因为默认下载到当前目录,这样就可以下载到自己制定的目录‘)
ftp = FTP('192.168.213.129')
ftp.login('root','westos')
print 'welcome'
print ftp.getwelcome()
ftp.cwd('/var/ftp/pub/pizi')
bufsize=1024 #设置缓冲块大小
list = ftp.nlst() #获得一个当前目录文件的的列表
for name in list: #用一个for循环取列表中的元素
print (name)
match = re.match(r'(.*)\.ack$',name) #匹配去除的元素,用正则
if match:
a = match.group(1) #如果匹配成功,取出.ack前面的文件名
if (a + ".dat"): #然后在查看是否有同名字的.dat文件
b=a.split('-')
###将a按-分割
b[6]=time.strftime('%H%M',time.localtime(time.time()))
###获取当前的时间 年月,将下标为6的元素替换
c='-'.join(b)
###将b按-合并成字符串
ftp.retrbinary("RETR %s"%a+".dat",open(c+".dat",'wb').write)
#如果两文件都存在,下载.dat文件,并且open里边的wb参数可以更改
#wb是以二进制模式下载,wt是以ASCII模式下载
ftp.delete(name)
#删除匹配上的.ack文件
ftp.delete(a + ".dat")
#删除匹配上的.dat文件
else:
continue
ftp.quit()
print "ftp down ok"
4. 登录ftp服务器的方法有很多,并且匹配在此可以不用正则,用spilt分割可能更简单,方法有很多,能实现就行。
5.现在粘上加入异常捕捉后的代码
#############################################
# Name: Ftp download
# Author: LCY
# Version: 1.0.20150826
# Feature: Download and determine if you are downloading.If you are downloading, exiting the script.
#############################################
#!/usr/bin/python
#coding=utf-8
import ftplib
import os
import socket
import sys
import re
import time
#os.chdir('/cstreaming/impalacsv')
#HOST = 'IP'
#DIRN = '/DRITARY'
#USER_NAME = 'NAME'
#PWD = 'PASSWD'
os.chdir('/root/Desktop')
HOST = '172.16.10.129'
DIRN='/var/ftp/pub/pizi'
USER_NAME='root'
PWD='westos'
def DownloadFile():
try:
f = ftplib.FTP(HOST)
except(socket.error, socket.gaierror) as e:
print('ERROR:cannot reach %s' % HOST)
return
print('*** Connected to host %s' % HOST)
try:
f.login(USER_NAME, PWD)
except ftplib.error_perm:
print('ERROR:cannot login USER_NAME=%s, PWD=%s' % (USER_NAME, PWD))
f.quit()
return
print('*** Logined in as %s' % USER_NAME)
try:
f.cwd(DIRN)
except ftplib.error_perm:
print('ERROR:cannot CD to %s' % DIRN)
f.quit()
return
try:
list = f.nlst()
for file_name in list:
match = re.match(r'(.*)\.dat$',file_name)
if match:
a = match.group(1)
b=a.split('-')
# b[4]=time.strftime('%Y%m%d%H%M',time.localtime(time.time()))
# b[4]='20'+b[4]
timeArry = time.strptime(b[4],"%y%m%d%H%M")
otherStyleTime = time.strftime("%Y%m%d%H%M",timeArry)
b[4]=otherStyleTime
g=b[4]+"-"+b[3]+"-"+b[0]+"-"+b[1]+"-"+b[2]+".DAT"
f.retrbinary("RETR %s"%a+".dat",open(g,'wb').write)
f.delete(file_name)
print "Ftp file Downloaded success"
else:
continue
except ftplib.error_perm:
print('ERROR:cannot read file %s' % file_name)
os.unlink(file_name)
#file.close()
else:
print('*** Downloaded %s to %s' % (file_name, os.getcwd()))
f.quit()
return
def is_Running(process):
try:
pids = os.popen("ps -ef | egrep 'python.*%s' | grep -v grep | awk '{print $2}' " % process)
for pid in pids.readlines():
if pid != '' and int(pid) != os.getpid():
return True
return False
except Exception,e:
return False
if __name__ == '__main__':
if is_Running('back_newftp.py'):
print 'back_newftp is running ,exit.'
exit(1)
else:
print 'start back_newftp.py'
DownloadFile()
新浪微博