当前需求:从FTP服务器上下载文件到本机,处理完成后,再把结果上传至FTP服务器指定路径下。

一、ftplib模块–FTP协议客户端

Python中默认安装的ftplib模块定义了FTP类,可以用来实现简单的ftp客户端,实现上传、下载文件功能。
说明手册ftplib — FTP protocol client — Python 3.5.9 documentation

1、FTP类及其方法

class FTP(host='', user='', passwd='', acct='', timeout=_GLOBAL_DEFAULT_TIMEOUT, source_address=None)

参数含义
host主机,调用connect(host)方法
user调用login方法
timeout超时参数,若不指定,则应用全局超时参数
source_address2个元组(主机,端口)
class FTP:
	# FTP client class
	debugging = 0
    host = ''
    port = FTP_PORT
    maxline = MAXLINE
    sock = None
    file = None
    welcome = None
    passiveserver = 1
    encoding = "latin-1"  #此处为默认编码模式
	
	# 初始化方法
	# 可选的参数是host(对于connect()),以及user, passwd, acct(对于login())
    def __init__(self, host='', user='', passwd='', acct='',
                timeout=_GLOBAL_DEFAULT_TIMEOUT, source_address=None):
       self.source_address = source_address
       self.timeout = timeout
       if host:
           self.connect(host)
           if user:
               self.login(user, passwd, acct)
名称含义
set_debuglevel()定义FTP.set_debuglevel(level)
功能:设置实例的调试级别,0:不输出(缺省值),1:中等调试输出,通常每个请求一行,2:显示详细信息
connect()定义FTP.connect(host='', port=0, timeout=None, source_address=None)
功能:连接到给定的主机和端口。默认端口号是21,由FTP协议规范指定。很少需要指定其他端口号。每个实例只应调用一次该函数。如果在创建实例时给出了主机,则根本不应该调用它。所有其他方法只能在建立连接后使用。可选的timeout参数指定连接尝试的超时时间(以秒为单位)。如果没有超时,则使用全局默认超时设置。source_address是2个元组(主机,端口),套接字在连接之前绑定为其源地址。
getwelcome()定义FTP.getwelcome()
功能:返回服务器发送的欢迎消息以回复初始连接。(此消息有时包含与用户有关的免责声明或帮助信息。)
login()定义FTP.login(user='', password='', acct='')
功能:以给定用户身份登录, passwordacct参数是可选的,默认为空字符串。如果用户未指定,则默认为anonymous。如果用户为anonymous,则默认密码为anonymous@。建立连接后,每个实例只能调用一次此函数。大多数FTP命令仅在客户端登录后才被允许。
abort()定义FTP.abort()
功能:中止正在进行的文件传输。不一定总是可以使用,但值得一试。
sendcmd()定义FTP.sendcmd(cmd)
功能:将简单的命令字符串发送到服务器并返回响应字符串。
voidcmd()定义:FTP.voidcmd(cmd)
功能:将简单的命令字符串发送到服务器并处理响应。如果收到与成功相对应的响应代码(范围在200-299之间的代码),则不返回任何内容。否则,请引发error_reply
retrbinary()定义retrbinary(self, cmd, callback, blocksize=8192, rest=None) 功能:以二进制模式获取文件。
参数
cmd:是一个RETR命令:RETR filenamefilename为要获取文件的完整路径+名称 callback :在读取的每个数据块上可调用的回调函数,使用单个字节参数指定数据块 blocksize:可选参数,实际传输的数据块的最大尺寸(这也是传递给回调的数据块的最大大小)
返回值:响应代码
retrlines()定义:FTP.retrlines(cmd, callback = None)
功能:以ASCII传输模式获取文件或目录列表
参数cmdRETR命令,或者诸如LISTNLST之类的命令。每一行都使用一个字符串参数调用回调函数。默认将回调行打印到sys.stdout
storbinary()定义FTP.storbinary(cmd, fp, blocksize=8192, callback=None, rest=None)
功能:以二进制传输模式存储文件,即上产本地文件至FTP服务器
参数
cmd:合适的STOR命令:“STOR filename”
fp:文件对象,以read()方法读取文件直到EOF
blocksize:默认值为8192,数据库大小
callback:可选参数,在每个数据库发送后调用
返回值:响应代码
storlines()定义FTP.storlines(cmd, fp, callback=None)
功能:以ASCII模式存储文件,创建一个新的端口
参数
cmd:合适的STOR命令
fp:文件对象,以read()方法读取文件直到EOF
set_pasv()定义set_pasv(val)
功能:设置传输数据使用主动模式还是被动模式
参数valtrue表示使用被动模式(PASV命令),false表示使用正常的PORT模式。默认是true
size()定义FTP.size(filename)
功能:请求服务器上名为filename的文件的大小。成功后,将以整数形式返回文件的大小,否则返回None
quit()定义FTP.quit()
功能:将QUIT命令发送到服务器并关闭连接。这是关闭连接的“礼貌”方式,但是如果服务器响应QUIT命令错误,则可能会引发异常。这意味着将调用close()方法,从而使FTP实例无法用于后续调用。
close()定义FTP.close()
功能:单方面关闭连接,这不应该用于已经关闭的连接,例如,已经成功调用quit()之后。在此调用之后,不应该再使用FTP实例(在调用close()quit()之后,将无法通过发出另一个login()方法再来重新打开连接)

2、ftplib常用方法

FTP登录连接

from ftplib import FTP			# 导入FTP模块
ftp = FTP()						# 设置变量
ftp.set_debuglevle(2)			# 设置实例的调试级别,0:不输出(缺省值),1:中等调试输出,通常每个请求一行,2:显示详细信息
ftp.connect(host='', port=0)	# 连接到给定的主机和端口(默认21),很少需要指定其他端口号。
ftp.getwelcome()				# 打印出欢迎信息
ftp.login('user', 'password')	# 以用户身份登录
ftp.abort()						# 中止正在进行的文件传输
ftp.retrbinary("RETR filename", fp, blocksize)		# 接受服务器上的文件并写入本地文件
ftp.storbinary("STOR filename", fp, blocksize)		# 以二进制传输模式存储文件,即上传文件至FTP服务器
ftp.set_pasv()					# 设置模式, true为被动模式(默认值),false为主动模式
ftp.quit()						# 退出ftp

FTP其他操作

ftp.cwd(pathname)				# 设置FTP当前操作的路径
ftp.dir()						# 显示目录下所有目录信息
ftp.nlist()						# 获取目录下的文件
ftp.mkd(pathname)				# 新建远程目录
ftp.pwd()						# 返回当前所在位置
ftp.rmd(dirname)				# 删除远程目录
ftp.delete(filename)			# 删除远程文件
ftp.rename(fromname, toname)	# 将fromname修改为toname
ftp.size(filename)				# 请求服务器上名为filename的文件的大小

二、代码示例

通过上面的介绍,已经对ftplib的函数有了一定的了解,接下来就是如果使用,下面会给出一个基本的文件上传、下载代码示例,可根据具体使用进行调整。

from ftplib import FTP
from ftplib import error_perm

class FTP_OP():
    def __init__(host, uesrname, password, port):
        self.host = host
        self.username = username
        self.password = password
        self.port = port
        
    def ftp_connect(self):
        self.ftp = FTP()
        self.ftp.encoding = 'UTF-8' # 适应中文编码
        try:
            self.ftp.set_debuglevel(2) # 调试级别
            self.ftp.connect(self.host, self.port)
            self.ftp.login(self.username, self.password)
            self.ftp.set_pasv(false) # 设置被动模式
        except error_perm:
            print('[ERROR]: user authentication failed.')
            return -1
        except Exception as e:
            print('[ERROR]: ftp connect failed. %s'%e)
            return -1
        print('***ftp success connected.***')
    
    def download_file(self, ftp_file, local_file):
        # 从ftp服务器上下载文件到本地
        # ftp_file: 远端要下载的文件
        # local_file: 保存到本地文件
        bufsize = 1024
        with open(local_file, 'wb') as f:
            self.ftp.retrbinary("RETR %s"%ftp_file, f.write, bufsize)
            
    def upload_file(self, ftp_file, local_file):
        # 上传本地文件至ftp服务器
        # ftp_file:保存至ftp的文件名
        # local_file:本地文件
        bufsize = 1024
        with open(local_file, 'rb') as f:
            self.ftp.storbinary("STOR %s"%ftp_file, f, bufsize)
            
    def ftp_quit(self):
        # 退出ftp
        self.ftp.quit()
        
if __name__ == '__main__':
    ftp = FTP("192.168.x.x", 'admin', '123', 21)
    ftp.ftp_connect()
    
    ftp_filename = '/abc.jpg'
    local_filename = './test/abc.jpg'
    
    # 下载文件至本地
    ftp.download_file(ftp_filename, local_filename)
    # 上传本机文件至ftp服务器
    ftp.upload_file('/abc_upload.jpg', local_filenaem)
    
    ftp.ftp_quit()

三、搭建FTP服务器的Server端

该部分转自: Python实现FTP服务功能 - HuZixia - 博客园

代码如下:

# -*- coding:utf-8 -*-
from pyftpdlib.authorizers import DummyAuthorizer
from  pyftpdlib.handlers  import FTPHandler
from  pyftpdlib.servers import FTPServer

# 实例化DummyAuthorizer来创建ftp用户
authorizer = DummyAuthorizer()

# 参数:用户名,密码,目录,权限
authorizer.add_user('admin', '123456', r'C:\Users\Administrator\Desktop\ftp', perm='elradfmwMT')
# 匿名登录
# authorizer.add_anonymous('/home/nobody')

handler = FTPHandler
handler.authorizer = authorizer

# 参数:IP,端口,handler
server = FTPServer(('0.0.0.0', 2121), handler)           #设置为0.0.0.0为本机的IP地址
server.serve_forever()

参考文献:

  1. python ftplib 模块的使用_小蚂蚁cc的博客-CSDN博客_ftplib
  2. python ftplib模块 - jihite - 博客园
Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐