前言
Python内置模块ftplib,可以轻松实现从ftp服务器上下载所需要的文件,包括目录结构
正文
FTP协议
- FTP(File Transfer Protocol,文件传输协议) 是TCP/IP协议组中的协议之一。FTP协议包括两个组成部分,其一为FTP服务器,其二为FTP客户端。其中FTP服务器用来存储文件,用户可以使用FTP客户端通过FTP协议访问位于FTP服务器上的资源。
- 默认情况下FTP协议使用TCP端口中的 20和21这两个端口,其中20用于传输数据,21用于传输控制信息。
python ftplib模块
python中默认安装的ftplib模块定义了FTP类,可用来实现简单的ftp客户端,用于上传或下载ftp服务器上的文件。
ftplib模块官方文档:https://docs.python.org/3/library/ftplib.html#module-ftplib
ftplib源码:https://github.com/python/cpython/blob/3.7/Lib/ftplib.py
ftp模块常用函数和命令
from ftplib import FTP # 导入ftplib模块
ftp=FTP() # 获取ftp变量
ftp.set_debuglevel(2) # 打开调试级别2,显示详细信息
ftp.connect("host","port") #连接的ftp sever服务器
ftp.login("usrname","password") # 用户登陆
print(ftp.getwelcome()) # 打印欢迎信息
ftp.cmd("xxx/xxx") # 进入远程目录
ftp.retrbinaly("RETR filename.txt",file_handle,bufsize) # 接收服务器上文件并写入本地文件
ftp.set_debuglevel(0) #关闭调试模式
ftp.quit() #退出ftp
ftp.cwd(ftppath) # 设置ftp当前操作的路径
ftp.dir() # 显示目录下所有文件信息
ftp.nlst() # 获取目录下的文件,返回一个list
ftp.mkd(pathname) # 新建远程目录
ftp.pwd() # 返回当前所在路径
ftp.rmd(dirname) # 删除远程目录
ftp.delete(filename) # 删除远程文件
ftp.rename(fromname, toname) # 将fromname修改名称为toname。
ftp.storbinaly("STOR filename.txt",fid,bufsize) # 上传目标文件
ftp.retrbinary("RETR filename.txt",fid,bufsize) # 下载FTP文件
下面以一个FtpDownload.py脚本为例,实现ftp批量下载
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2019/4/11 17:28
# @Author : zengsk in HoHai
import os
import sys
from ftplib import FTP
# 连接ftp服务器
def ftpConnect(ftpserver, port, usrname, password):
ftp = FTP()
try:
ftp.connect(ftpserver, port)
ftp.login(usrname, password)
except:
raise IOError('\n FTP connection failed, please check the code!')
else:
print(ftp.getwelcome()) # 打印登陆成功后的欢迎信息
print('\n+------- ftp connection successful!!! --------+')
return ftp
# 下载单个文件
def ftpDownloadFile(ftp, ftpfile, localfile):
# fid = open(localfile, 'wb') # 以写模式打开本地文件
bufsize = 1024
with open(localfile, 'wb') as fid:
ftp.retrbinary('RETR {0}'.format(ftpfile), fid.write, bufsize) # 接收服务器文件并写入本地文件
return True
# 下载整个目录下的文件
def ftpDownload(ftp, ftpath, localpath):
print('Remote Path: {0}'.format(ftpath))
if not os.path.exists(localpath):
os.makedirs(localpath)
ftp.cwd(ftpath)
print('+---------- downloading ----------+')
for file in ftp.nlst():
print(file)
local = os.path.join(localpath, file)
if os.path.isdir(file): # 判断是否为子目录
if not os.path.exists(local):
os.makedirs(local)
ftpDownload(ftp, file, local) # 递归调用
else:
ftpDownloadFile(ftp, file, local)
ftp.cwd('..')
ftp.quit()
return True
# 退出ftp连接
def ftpDisConnect(ftp):
ftp.quit()
# 程序入口
if __name__ == '__main__':
# 输入参数
ftpserver = 'jsimpson.pps.eosdis.nasa.gov'
port = 21
usrname = '[email protected]'
pwd = 'xxxxxxxxxxxxxx'
ftpath = '/NRTPUB/imerg/late/201403/'
localpath = 'D:/data/'
ftp = ftpConnect(ftpserver, 21, usrname, pwd)
flag = ftpDownload(ftp, ftpath, localpath)
print(flag)
ftpDisConnect(ftp)
print("\n+-------- OK!!! --------+\n")
把FtpDownload.py封装成一个类 -->FtpDownloadCls.py,两种方式的实现效果一样
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2019/4/12 22:00
# @Author : zengsk in HoHai
'''
FTP批量下载数据
'''
import os
import sys
from ftplib import FTP
class FtpDownloadCls:
def __init__(self, ftpserver, port, usrname, pwd):
self.ftpserver = ftpserver # ftp主机IP
self.port = port # ftp端口
self.usrname = usrname # 登陆用户名
self.pwd = pwd # 登陆密码
self.ftp = self.ftpConnect()
# ftp连接
def ftpConnect(self):
ftp = FTP()
try:
ftp.connect(self.ftpserver, self.port)
ftp.login(self.usrname, self.pwd)
except:
raise IOError('\n FTP login failed!!!')
else:
print(ftp.getwelcome())
print('\n+------- FTP connection successful!!! --------+\n')
return ftp
# 单个文件下载到本地
def downloadFile(self, ftpfile, localfile):
bufsize = 1024
with open(localfile, 'wb') as fid:
self.ftp.retrbinary('RETR {0}'.format(ftpfile), fid.write, bufsize)
return True
# 下载整个目录下的文件,包括子目录文件
def downloadFiles(self, ftpath, localpath):
print('FTP PATH: {0}'.format(ftpath))
if not os.path.exists(localpath):
os.makedirs(localpath)
self.ftp.cwd(ftpath)
print('\n+----------- downloading!!! -----------+\n')
for i, file in enumerate(self.ftp.nlst()):
print('{0} <> {1}'.format(i, file))
local = os.path.join(localpath, file)
if os.path.isdir(file): # 判断是否为子目录
if not os.path.exists(local):
os.makedirs(local)
self.downloadFiles(file, local)
else:
self.downloadFile(file, local)
self.ftp.cwd('..')
return True
# 退出FTP连接
def ftpDisConnect(self):
self.ftp.quit()
# 程序入口
if __name__ == '__main__':
# 输入参数
ftpserver = 'hokusai.eorc.jaxa.jp' # ftp主机IP
port = 21 # ftp端口
usrname = 'rainmap' # 登陆用户名
pwd = 'Niskur+1404' # 登陆密码
ftpath = '/standard/v7/daily/00Z-23Z/201403' # 远程文件夹
localpath = 'D:/data/GSMaP/' # 本地文件夹
Ftp = FtpDownloadCls(ftpserver, port, usrname, pwd)
Ftp.downloadFiles(ftpath, localpath)
Ftp.ftpDisConnect()
print("\n+-------- OK!!! --------+\n")
总结
- 毕业、工作,她签的第一个公司,是国际知名的外企。当她在合同上签下名字的时候,HR突然悠悠地说了一句:“你的英文不如母语好,回去自己加强一下。”
- 英语怎么可能比母语好?她先是疑惑了一下,却又立刻意识到周围的每一个人,从总监、秘书到前台,竟然都做到了这一点。
- 要拿什么,才能弥补这个弱点呢?直到她在杂志上看到了这样一句话——每个人都要在职场有自己的核心竞争力。
- 也许我一辈子都没法把英文说得像母语那样好,但我可以做中文最好的那个人。
————特立独行的猫