问题:续接上一篇。说干咱就干呀,勤勤恳恳写程序呀!

目标:此篇开始进入正题了。为实现我们整个项目功能而开始实现各个子模块功能。首先实现第一篇列出的分步功能模块的第一步:

1、python访问ftp,下载所有文件到本地文件夹DownloadData

解决方案:查找python访问ftp并下载文件的相关资料,编写涉及的功能函数,并将其封装在一个通用的FTPHelper类中。这样方便使用和维护。

具体相关项分析:

1、ftp对象信息:ftp主机名称或者ip地址,端口(默认是21),登录名称,登录密码。

2、成功连接上ftp后的操作:某指定的路径是否是文件路径,某指定的路径是否是文件夹路径,获取某指定的路径下的所有文件名,下载某指定的路径下的所有文件。

3、python实现操纵ftp需要引用什么模块?ftplib。

python是依赖功能包来实现一些常见的功能的,因此安装和引用功能包是使用python编程的常见步骤。

具体实践:

1、新建了一个类: FTPHelper.py。

首行添加代码:import ftplib ,引用ftplib包。定义conn 连接对象,类初始化时连接ftp,定义login登录函数。

  1. conn = ftplib.FTP()
  2.  
  3. def __init__(self, host, port=21):
    self.conn.connect(host, port)
  4.  
  5. def login(self, username, password):
    self.conn.login(username, password)
    self.conn.set_pasv(True)
    print("FTPHelper init")
    # print(self.conn.welcome)

2、定义相关功能函数

  1. def _is_ftp_dir(self, ftp_path): # 私有函数:是否是ftp路径
    ftp_path = ftp_path.rstrip('/')
    ftp_path_parent = os.path.dirname(ftp_path)
    self.ftp_dir_name = os.path.basename(ftp_path)
    self._is_dir = False
    if ftp_path == '.' or ftp_path == './' or ftp_path == '':
    self._is_dir = True
    else:
    # this use callback function ,that will change _is_dir value
    try:
    self.conn.retrlines('LIST %s' % ftp_path_parent, self._ftp_list)
    except ftplib.error_perm as e:
  1. return self._is_dir
    return self._is_dir
  2.  
  3. def _ftp_list(self, line):
    list = line.split(' ')
    if self.ftp_dir_name == list[-1] and list[0].startswith('d'):
    self._is_dir = True
  4.  
  5. def _is_ftp_file(self, ftp_path): # 私有函数:是否是ftp文件
    try:
    if ftp_path in self.conn.nlst(os.path.dirname(ftp_path)):
    return True
    else:
    return False
    except ftplib.error_perm as e:
    return False
  1. def download_files_from_dir(self, ftp_path, local_path='.', begin=False):
    try:
    ftp_path = ftp_path.rstrip('/')
    # 当ftp目录存在时下载
    if self._is_ftp_dir(ftp_path):
    # 将指定路径ftp_path文件夹中的文件下载到本地。
    # begin=True,则将ftp文件夹名作为本地保存文件夹名。
    # 如果本地目录不存在,则创建目录。
  2.  
  3. if begin:
    if not os.path.isdir(local_path):
    os.makedirs(local_path)
    local_path = os.path.join(local_path, os.path.basename(ftp_path))
    # 如果本地目录不存在,则创建目录
    if not os.path.isdir(local_path):
    os.makedirs(local_path)
    # 进入ftp目录,开始递归查询
    self.conn.cwd(ftp_path)
    ftp_files = self.conn.nlst()
    for file in ftp_files:
    local_file = os.path.join(local_path, file)
    # 如果file ftp路径是文件则直接上传文件
    if not self._is_ftp_dir(file):
    self.get_file(file, local_file)
    # else:
    # print(file + " is dir.")
    # 如果当前ftp目录文件已经遍历完毕返回上一层目录
    self.conn.cwd("..")
    return
    else:
    print('ERROR:The dir:%s is not exist' % ftp_path)
    return
    except Exception as e:
    print(e)
  4.  
  5. def get_files_name_from_dir(self, ftp_path):
    try:
    ftp_path = ftp_path.rstrip('/')
    # 当ftp目录存在时下载
    if self._is_ftp_dir(ftp_path):
    # 将指定路径ftp_path文件夹中的文件名返回。
    # 返回:list。
    # 进入ftp目录,开始递归查询
  6.  
  7. self.conn.cwd(ftp_path)
    ftp_files = self.conn.nlst()
    array_data = []
    for file in ftp_files:
    # 如果file ftp路径是文件则收录
    if not self._is_ftp_dir(file):
    array_data.append(file)
    # else:
    # print(file + " is dir.")
    # 如果当前ftp目录文件已经遍历完毕返回上一层目录
    self.conn.cwd("..")
    return array_data
    else:
    print('ERROR:The dir:%s is not exist' % ftp_path)
    LogHelper.LogHelper.write_msg2log_file('ERROR:The dir:%s is not exist' % ftp_path, self.PROJECT_NAME)
    return []
    except Exception as e:
    print(e)
    LogHelper.LogHelper.write_msg2log_file("[" + sys._getframe().f_code.co_name + "]" + e, self.PROJECT_NAME)
    return []
  1.  

3、定义测试函数test并添加到主函数执行

  1. def test():
    ftp = FTPHelper('xxx')
    ftp.login('xxx', 'xxx')
  2.  
  3. # 下载文件夹到本地的文件夹
    local_path = os.path.join(os.path.dirname(sys.argv[0]), "DownloadFiles")
    ftp.download_files_from_dir('A/B', local_path)
    print(ftp.get_files_name_from_dir('A'))
  4.  
  5. if __name__ == '__main__':
    test()
  6.  

参考地址:http://www.jb51.net/article/67196.htm

Python3实战系列之四(获取印度售后数据项目)的更多相关文章

  1. Python3实战系列之一(获取印度售后数据项目)

    问题:公司在印度开设生产工厂并在当地销售手机,生产.销售系统均由印度开发维护.对总部需要的售后数据,采用每日在ftp上提供一个.xlsx文件,给总部使用.总部需要将此数据导入到总部的销量统计系统中,以 ...

  2. Python3实战系列之七(获取印度售后数据项目)

    问题:续接上一篇.说干咱就干呀,勤勤恳恳写程序呀! 目标:此篇开始进入正题了.为实现我们整个项目功能而开始实现各个子模块功能.首先实现第一篇列出的分步功能模块的第四步: 4.python读取excel ...

  3. Python3实战系列之九(获取印度售后数据项目)

    项目现状:已经部署在服务器上并正常运行了. 1.服务器上的部署 2.下载到服务器的文件列表 3.转存在到数据库SQL Server中的数据 项目总结:这次项目采用python来实现,刚开始还是有点担忧 ...

  4. Python3实战系列之八(获取印度售后数据项目)

    问题:续接上一篇.说干咱就干呀,勤勤恳恳写程序呀! 目标:此篇开始进入正题了.为实现我们整个项目功能而开始实现各个子模块功能.首先实现第一篇列出的分步功能模块的第五步: 5.python连接SQL S ...

  5. Python3实战系列之六(获取印度售后数据项目)

    问题:续接上一篇.说干咱就干呀,勤勤恳恳写程序呀! 目标:此篇我们试着把python程序打包成.exe程序.这样就可以在服务器上运行了.实现首篇计划列表功能模块的第三步: 3..exe文件能在服务器上 ...

  6. Python3实战系列之二(获取印度售后数据项目)

    问题:续接上一篇.说干咱就干呀,勤勤恳恳写程序呀! 目标:安装python和pycharm.要编写并运行python程序就需要电脑有开发工具和运行环境,所以此篇就是安装编辑和运行python程序的软件 ...

  7. Python3实战系列之五(获取印度售后数据项目)

    问题:续接上一篇.说干咱就干呀,勤勤恳恳写程序呀! 目标:此篇我们试着把python程序打包成.exe程序.这样就可以在服务器上运行了.实现首篇计划列表功能模块的第二步: 2.将python程序转为 ...

  8. Python3实战系列之三(获取印度售后数据项目)

    问题:续接上一篇.说干咱就干呀,勤勤恳恳写程序呀! 目标:实现第一个python程序的“Hello world!” 解决方案:新建一个项目Test,创建一个Test.py文件.在文件中实现打印出“He ...

  9. 单元测试系列之四:Sonar平台中项目主要指标以及代码坏味道详解

    更多原创测试技术文章同步更新到微信公众号 :三国测,敬请扫码关注个人的微信号,感谢! 原文链接:http://www.cnblogs.com/zishi/p/6766994.html 众所周知Sona ...

随机推荐

  1. lua keynote

    [lua keynote] 1.两个减号是单行注释: -- --[[ 多行注释 多行注释 --]] ---[[ // 三个'-'开启的是一个行注释--]] 1.1.两条语句可以在同一行,并表不需要分号 ...

  2. Webpack Plugin

    [Webpack Plugin] Since Loaders only execute transforms on a per-file basis, plugins are most commonl ...

  3. css设计技巧

    如果设置了样式发现没有效果,可以把需要调的元素或者父元素等设置一下背景,然后看看哪个父元素或子元素有样式控制,可以清除一下.

  4. c3p0的几种使用方式(原文地址: https://my.oschina.net/liangtee/blog/101047)

    package com.c3p0.test; import java.sql.Connection; import java.sql.SQLException; import java.beans.P ...

  5. 第十章 优先级队列 (xa3)左式堆:插入与删除

  6. Serializers序列化组件

    Django的序列化方法 .values 序列化结果 class BooksView(View): def get(self, request): book_list = Book.objects.v ...

  7. lower_bound和upper_bound的实现和基本用法

    最近一直在学dp,但是感觉进度明显慢了很多,希望自己可以加一把劲,不要总是拖延了... 在LIS的优化中我遇到了二分查找的问题,之前也知道lower_bound和upper_bound两个函数,但是没 ...

  8. TOJ1302: 简单计算器 && TOJ 4873: 表达式求值&&TOJ3231: 表达式求值

    这些都是应用Python的eval函数的一些题目! TOJ1302传送门:http://acm.tzc.edu.cn/acmhome/problemdetail.do?&method=show ...

  9. 随机数、方法重载和System.out.println()的理解

    1.编写一个方法,使用以上算法生成指定数目(比如1000个)的随机数. package testradom; public class testradom { public static void m ...

  10. dUMP:A new value is to be assigned to the field "<L_BOX>"

    DUMP: A new value is to be assigned to the field "<L_BOX>", although this field is e ...