前提摘要:

本篇文章主要是介绍如何实现FTP上传下载文件,也相当于项目经验的一个介绍吧。在我们的实际项目中文件传输其实用的是FTPS,关于FTP大家应该不陌生,那么FTPS是什么东西呢? 简单一句话概括:类似于http 和https的关系。也就是说FTPS就是加密过的FTP。

关于详细的FTP 和 FTPS的关系下面这篇文章说的更清晰一些:

https://blog.csdn.net/yumeng8525/article/details/17758553

项目介绍:

首先介绍一下,python有专门ftp相关的第三方库:ftplib,关于ftplib的信息网上有很多,但是我觉得最有用的还是看源码,或者官方文档:

https://docs.python.org/zh-cn/3/library/ftplib.html?highlight=ftplib

ftplib中有两个大类:FTP 和 FTP_TLS, 其中FTP_TLS的类,是专门用于FTPS的;该类其实也是继承了FTP类的;也就是FTP的子类,这里大家可以看下源码,我这里不做赘述了。

接下来会贴一些代码,边看边解释:

step 1:

在使用之前需要先导入FTP_TLS, 因为FTP_TLS的类是class FTP的子类,所以也拥有FTP类的所有方法。

from ftplib import FTP_TLS

step 2:

接下来就是建立ftps连接了

 def open_ftps_connection(self, host=None, username=None, password=None, port=990):host = host if host is not None else self._device.active_device().ipAddressusername = username if username is not None else self._device.active_device().rbacUsernamepassword = password if password is not None else self._device.active_device().rbacPasswordself.ftps = _FTPS()self.ftps.connect(host=host, port=port)try:self.ftps.login(username, password)self.ftps.prot_p()self._access = Trueexcept Exception as err:if 'Not logged in' in str(err):self._access = Falselogger.error('Login ftp server error :{}'.format(err))self.close_ftps_connection()return self.ftps

由于连接时报错,这时候就需要修改源码了,但是直接修改源码肯定不是最明智的选择;但是我们可以重写源码中的方法,来实现我们想要的效果。我这里是重写了一个名为_FTPS的类,继承FTP_TLS类,然后在类中重写了connect 方法和 nlst 方法:

#region FTPS Operation Helper Classclass _FTPS(FTP_TLS):def __init__(self, *args):super().__init__(*args)def connect(self, host='', port=0, timeout=-999, source_address=None):'''The original connect function could not successfully connect our device, so we reconstructed this function'''if host != '':self.host = hostif port > 0:self.port = portif timeout != -999:self.timeout = timeoutif source_address is not None:self.source_address = source_addressself.sock = socket.create_connection((self.host, self.port), self.timeout, source_address=self.source_address)self.af = self.sock.familyself.sock = ssl.wrap_socket(self.sock, self.keyfile, self.certfile, ssl_version=ssl.PROTOCOL_TLSv1_2)self.file = self.sock.makefile('r', encoding=self.encoding)self.welcome = self.getresp()return self.welcomedef nlst(self, *args):'''The original nlst method in ftplib does not list complete files, so the nlst method is reconstructed here'''cmd = 'LIST'templist = []func = Noneif args[-1:] and type(args[-1]) != type(''):args, func = args[:-1], args[-1]for arg in args:if arg:cmd = cmd + (' ' + arg)self.retrlines(cmd, templist.append)return templist#endregion

其中,重写connect方法就是增加了一行:ssl_version参数赋值你们项目所用的tls 版本即可,我们这里用的是tls 1.2

self.sock = ssl.wrap_socket(self.sock, self.keyfile, self.certfile, ssl_version=ssl.PROTOCOL_TLSv1_2)

其中,重写nlst方法是因为原有的nlst方法并不能列出所有的文件,所以稍作修改。

step 3:

基础工作完成之后就可以封装FTPS相关的函数给项目使用了。

1.是建立ftps连接的函数;很简单,没啥可介绍的,其中添加的一个self._acess类属性是为了其他函数使用的,目的是为了验证该账号是否有ftps的登录权限(因为装置根据不同角色做了权限限制)

 def open_ftps_connection(self, host=None, username=None, password=None, port=990):host = host if host is not None else self._device.active_device().ipAddressusername = username if username is not None else self._device.active_device().rbacUsernamepassword = password if password is not None else self._device.active_device().rbacPasswordself.ftps = _FTPS()self.ftps.connect(host=host, port=port)try:self.ftps.login(username, password)self.ftps.prot_p()self._access = Trueexcept Exception as err:if 'Not logged in' in str(err):self._access = Falselogger.error('Login ftp server error :{}'.format(err))self.close_ftps_connection()return self.ftps

2.关闭ftps连接的函数;更简单,就是调用了ftp已有的方法(其实就是发送了一条‘QUIT’命令)。

 def close_ftps_connection(self):self.ftps.quit()

3.获取文件列表的函数;由于我们项目文件层级较多,所以这个函数主要是使用递归的方法来列出某一文件夹下所有的文件,并返回每个文件的绝对路径(为什么要返回绝对路径,因为FTP下载的时候需传入文件绝对路径)。

 def get_file_list_from_ftps(self, remoteFolder):self.filePath = [] # 全局变量self._get_ftps_file_path(remoteFolder) # 调用下面的私有函数return self.filePath # 返回全局变量,存放的是所有文件绝对路径def _get_ftps_file_path(self, remoteFolder):self.ftps.cwd(remoteFolder) # 进入文件夹remotePath = self.ftps.nlst() # 列出文件for path in remotePath:fullPath = os.path.join(remoteFolder, self._get_ftp_dir_name(path))if self._is_ftp_dir(path):self._get_ftps_file_path(fullPath) # 再次调用该函数,实现递归else:self.filePath.append(fullPath)def _is_ftp_dir(self, path):path = str(path)isDir = Falseif '<DIR>' in path:isDir = Truereturn isDirdef _get_ftp_dir_name(self, path):path = str(path)dirName = path.split(' ')[-1]return dirName

4.开始下载文件:很简单不多做介绍,就是传入文件名称,下载到什么路径,然后调用retrbinary方法即可。

 def download_file_from_ftps(self, filePath, destFilePath=None, bufsize=1024):if destFilePath is None:targetFolder = self._common.get_output_folder()filename = pathlib.PurePath(filePath).namedestFilePath = targetFolder / filenameelse:destFilePath = pathlib.Path(destFilePath)if destFilePath.exists():raise IOError('File {:s} already exists in test case file folder'.format(destFilePath.name))try:with open(destFilePath, 'wb') as f:self.ftps.retrbinary('RETR {}'.format(filePath), f.write, bufsize)except Exception as err:logger.error('Download file error :{}'.format(err))return destFilePath

5.验证用户是否有权限登录ftps服务器;因为我司项目中有多个角色的成员,admin,viewer,manager 等等,不同角色权限不同,有的角色是没有ftp权限的,所以这里写了两个函数,便于再robotframework中写case。

 def validate_user_can_access_ftps(self, username, password):logger.info('Validating user can access ftps with name:{} password:{}'.format(username, password))self.open_ftps_connection(username=username, password=password)if self._access:logger.info('User is able to access ftps server.')self.close_ftps_connection()else:raise AssertionError('User is unable to access ftps server.')def validate_user_can_not_access_ftps(self, username, password):logger.info('Validating user can not access ftps with name:{} password:{}'.format(username, password))self.open_ftps_connection(username=username, password=password)if self._access:self.close_ftps_connection()raise AssertionError('User is able to access ftps server.')else:logger.info('User is unable to access ftps server.')

step 4:

至此,ftps的基础操作的函数就完成了,接下来就是再次封装这些基础函数来下载不同类型的文件,便于在robotframework中构建case。往下就牵扯到具体业务相关内容了,也就没有太大参考意义,这里就不做赘述了。

写在最后:

总结:其实关于FTPS的操作没有太复杂的东西,因为ftp的方法可以直接看源码,即可直接使用了,我这里无非是根据项目需要做了一层封装,然后便于写case。如果对大家有帮助,那就再好不过了。

哎,拖延症患者终于再2021年最后一天把几个月前做的一个小项目总结了一下。。

python FTPS使用ftplib下载文件(详细)相关推荐

  1. python实现文件下载-python实现上传下载文件功能

    最近刚学python,遇到上传下载文件功能需求,记录下! django web项目,前端上传控件用的是uploadify. 文件上传 - 后台view 的 Python代码如下: @csrf_exem ...

  2. python电脑下载方法-python 获取机器snpython下载文件的几种常用方法

    python中下载文件常用的几个模块有urllib,urllib2,requests,方法也很简单,代码如下: 002pc.com从python 获取机器snpython下载文件的几种常用方法分析来看 ...

  3. python 文件上传下载,python实现上传下载文件功能

    最近刚学python,遇到上传下载文件功能需求,记录下! django web项目,前端上传控件用的是uploadify. 文件上传 - 后台view 的 Python代码如下: @csrf_exem ...

  4. Python根据URL地址下载文件并保存至对应目录

    Python根据URL地址下载文件并保存至对应目录 引言 在编程中经常会遇到图片等数据集将图片等数据以URL形式存储在txt文档中,为便于后续的分析,需要将其下载下来,并按照文件夹分类存储.本文以Gi ...

  5. Python爬虫之scrapy下载文件和图片

    Python爬虫之scrapy下载文件和图片 一:pipeline 二:使用scrapy下载图片 2.1 创建scrapy项目 1.2 创建爬虫 1.3 配置文件设置 1.4 编写启动文件 1.5 爬 ...

  6. python ftplib下载文件封装

    原用于下载ftp中文路径图片封装代码 支持指定用户密码和端口 ftp://ftpuser:ftppasswd@192.168.2.157:21/test.png 支持中文 ftp://192.168. ...

  7. python(24)下载文件

    利用程序自己编写下载文件挺有意思的.Python中最流行的方法就是通过Http利用urllib或者urllib2模块.当然你也可以利用ftplib从ftp站点下载文件.此外Python还提供了另外一种 ...

  8. python ftp上传/下载文件,带进度条显示

    文章目录 想法 最终效果 python代码 补充:下载带进度显示 想法 用python写个ftp上传文件的功能,想要实时看到上传进度,进度条ui部分,使用python的tkinter库实现. 最终效果 ...

  9. python批量下载文件-python 从远程批量下载文件到本地

    需求: 1.从postgresql数据库中查出附件名称 2.从远程服务器下载对应的附件 用到的python模块paramiko.psycopg2. paramiko是用python写的一个模块,遵循S ...

  10. python单击url下载网页文件_使用不带url的python脚本从网页下载文件,调用onClick函数 - javascript...

    有一个网页带有链接"单击下载",单击该链接可以下载文件. 我可以通过转到网页并单击此链接来手动下载此文件,但是我需要通过python脚本下载此文件. 如果我看到源代码,则可以看到锚 ...

最新文章

  1. 深挖数据价值 阿里云栖开年大会报道
  2. 微型计算机的什么接口主要作为打印机接口,微型计算机及其接口技术试题及答案(2006年10月)...
  3. c语言中指针的类型,学习C语言中的指针类型
  4. scala maven plugin
  5. 计算机组装方案及分析,《计算机组装与维护》课程整体教学方案
  6. 【Java】生成 .json格式文件工具类
  7. java中set语句_数据步骤中的多个SET / MERGE语句
  8. java juc 包_JUC java并发包
  9. java list map 效率_遍历Map和List的几种方法和性能比较
  10. NspAction与JsonAction区别与用法
  11. java简历编写及面试技巧
  12. 时隔三月,再次向你推荐这款公文排版插件
  13. 第一周挑战2:税后工资计算器
  14. 独家 | GAN大盘点,聊聊这些年的生成对抗网络 : LSGAN, WGAN, CGAN, infoGAN, EBGAN, BEGAN, VAE
  15. 学习java第14天
  16. matlab包络分析函数,数据包络分析 (MATLAB代码).doc
  17. android高德地图marker图标,图标样式-字体图标标注-示例中心-JS API UI 组件示例 | 高德地图API...
  18. 如何给apk安装包去毒,避免被识别为病毒和木马
  19. 渡者 逆向通关分析报告【配置文件】
  20. 持续交付(CD)简单介绍

热门文章

  1. 惠普m132nw清零方法_惠普HP打印机墨盒清零方法
  2. ModuleNotFoundError: No module named ‘keras.api‘解决
  3. 关于Python 向pdf添加印章效果的思考及实现
  4. 游戏设计的100个原理(11-15)
  5. android应用图标的尺寸大小,Android APP LOGO尺寸
  6. 可视化实验四:大数据可视化工具—ECharts(二)
  7. chipgenius芯片精灵v4|chipgenius芯片精灵 usb检测工具绿色版v4.00.1024下载
  8. Linux开发板网络连接
  9. iOS进阶:【1、 使用文件路径获取自定义字体名称2、添加资源包到工程→在info.plist文件中注册字体→在工程Bundle Resource中复制字体资源包→代码检测查询加入的字体并使用。】
  10. 这次,华为选择了湖南大学、湘潭大学