https://www.cnblogs.com/wangziyi0513/p/11077323.html

参考原始代码:

修改了一下:

许多网友问中文路径乱码怎么办,我觉得应该讲中文路径转码后再发送。

ftpath = '/home/omcr/文档/{}'.format(y).encode('utf-8').decode('latin-1')

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2019/4/12 22:00
# @Author : zengsk in HoHai
# edited by wh
'''
FTP批量下载数据
'''
import os
import sys
from ftplib import FTP
import datetime class FtpDownloadCls:
def __init__(self, ftpserver, port, usrname, pwd, encode1, decode1):
self.ftpserver = ftpserver # ftp主机IP
self.port = port # ftp端口
self.usrname = usrname # 登陆用户名
self.pwd = pwd # 登陆密码
self.ftp = self.ftpConnect()
# 用于中文编码解码,
self.encode1 = encode1
self.decode1 = decode1 # ftp连接
def ftpConnect(self):
ftp = FTP()
try:
ftp.connect(self.ftpserver, self.port)
ftp.login(self.usrname, self.pwd)
       # python ftplib 默认的编码方式是latin-1
self.encode1 = ftp.encoding
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
     # 要在本地正确的显示中文,需要先通过latin-1编码成unicode,在解码成utf-8或GBK
with open(localfile.encode(self.encode1).decode(self.decode1), '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__': yesterday = (datetime.datetime.now() - datetime.timedelta(days = 1))
y = yesterday.strftime("%Y%m%d")
# 输入参数
ftpserver = '10.20.20.1' # ftp主机IP
port = 21 # ftp端口
usrname = 'omcr' # 登陆用户名
pwd = 'abcd.1' # 登陆密码
#ftpath = '/export/home/omcr/UMS8800_WKM_TDL_V3.0.0_26_20171013/LTE_WKM/webapps/WKMService/reportfile/计划报表/20190623/' # 远程文件夹
# 想要将路径中的中文正确发送到ftp服务器,需要先通过本地编码utf-8转换为unicode,在编码为latin-1,这样才能被ftplib模块正确发送给ftp服务器,虽然发送过去的中文编码是乱的
# 但服务器可以识别
ftpath = '/home/omcr/文档/{}'.format(y).encode('utf-8').decode('latin-1')
localpath = 'D:/EC/data/{}'.format(y) # 本地文件夹(不要使用中文) Ftp = FtpDownloadCls(ftpserver, port, usrname, pwd, 'latin-1', 'utf-8')
Ftp.downloadFiles(ftpath, localpath)
Ftp.ftpDisConnect()
print("\n+-------- OK!!! --------+\n") # 删除多余文件
dirPath = r'D:/EC/data'
x = ''
for f in os.listdir(dirPath):
if not x in f:
os.remove(os.path.join(dirPath, f))

  实际使用脚本时,遇到几个问题:

1、没有遵守python语法,没有严格按空4个格的要求编写脚本,导致程序运行失败。

2、路径配置错误,solaris服务器路径从/export/home/......开始,linux服务器从/home/......开始,如果不注意,容易搞混。

3、服务器有两种中文编码:GBK和utf-8,容易搞混。

如果现场不会用cmd,则需要编写一个bat:

py ftpdown_weekendn.py

pause

放在py脚本同一目录下,双击bat脚本执行后,cmd窗口会停在最后报错的地方。

第二版:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2019/4/12 22:00
# @Author : zengsk in HoHai
# edited by wh '''
FTP批量下载数据
'''
import os
import sys
from ftplib import FTP
import datetime class FtpDownloadCls:
def __init__(self, ftpserver, usrname, pwd, decode1, port=21, encode1='latin-1'):
self.ftpserver = ftpserver # ftp主机IP
self.port = port # ftp端口
self.usrname = usrname # 登陆用户名
self.pwd = pwd # 登陆密码
self.ftp = self.ftpConnect()
# latin-1
self.encode1 = encode1
# 中文编码UTF-8或GBK
self.decode1 = decode1 # ftp连接
def ftpConnect(self):
ftp = FTP()
try:
ftp.connect(self.ftpserver, self.port, 30)
ftp.login(self.usrname, self.pwd)
self.encode1 = ftp.encoding
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, save='', delete='', saveset=set(), deleteset=set()):
ftppath_t = ftpath.encode(self.decode1).decode(self.encode1)
print('FTP PATH: {0}'.format(ftpath))
if not os.path.exists(localpath):
os.makedirs(localpath)
self.ftp.cwd(ftppath_t)
print('\n+----------- downloading!!! -----------+\n')
flist = set()
for i, file in enumerate(self.ftp.nlst()):
filename = file.encode(self.encode1).decode(self.decode1)
if save in filename and (delete not in filename or delete is ''):
flist.add(filename)
if saveset:
flist = flist.intersection(saveset)
flist = flist.difference(deleteset)
for i, f in enumerate(flist):
file = f.encode(self.decode1).decode(self.encode1)
print('{0} <> {1}'.format(i, f))
local = os.path.join(localpath, f)
self.downloadFile(file, local)
self.ftp.cwd('..')
return True # 退出FTP连接
def ftpDisConnect(self):
self.ftp.quit() # 程序入口
if __name__ == '__main__': # 取前三天或者前N天的日期
datelist = [(datetime.datetime.now() - datetime.timedelta(days = x)) for x in range(1,4)] # 输入参数
# 服务器中文编码方式,不是UTF-8就是GBK
s_code = 'GBK'
ftpserver = '10.9.0.25' # ftp主机IP
usrname = 'root' # 登陆用户名
pwd = 'aapswd' # 登陆密码 Ftp = FtpDownloadCls(ftpserver, usrname, pwd, s_code) for d in datelist:
# 小北向目录格式20190703
y = d.strftime("%Y%m%d")
ftppath1 = '/export/home/omcr/UMS_WKM_LTE-35/LTE_WKM/webapps/WKMService/reportfile/计划报表/{}/ENB/小时报表'.format(y)
ftppath2 = '/export/home/omcr/UMS_WKM_LTE-35/LTE_WKM/webapps/WKMService/reportfile/计划报表/{}/ENB/天报表'.format(y)
# 本地文件夹(不要使用中文)
localpath = r'D:/EC/EC_XBX/{}/'.format(y)
# 新增核对本地文件夹功能,有时ftp传输不稳定,没有传完就掉线了,需要二次执行脚本,这时本地路径下已有的文件就可以过滤出去,不必再次下载。
if os.path.exists(localpath):
existfiles = set(os.listdir(localpath))
else:
existfiles = set()
# downloadFiles(a,b,c,d,e,f)第3个参数是过滤后留下的,第4个参数是过滤掉的
Ftp.downloadFiles(ftppath1, localpath, '', '', deleteset=existfiles)
Ftp.downloadFiles(ftppath2, localpath, '', '', deleteset=existfiles) Ftp.ftpDisConnect()
print("\n+-------- OK!!! --------+\n") # 第2组参数
# 服务器中文编码方式,不是UTF-8就是GBK
s_code = 'GBK'
ftpserver = '10.2.0.12' # ftp主机IP
usrname = 'root' # 登陆用户名
pwd = 'root1234' # 登陆密码 Ftp = FtpDownloadCls(ftpserver, usrname, pwd, s_code) for d in datelist:
# OMC日期格式2019-07-02
y_m_d = d.strftime("%Y-%m-%d")
# 本地路径格式统一为20190703
y = d.strftime("%Y%m%d")
ftppath1 = '/export/home/omcrftp/pm/reports/{}'.format(y_m_d)
# 本地文件夹(不要使用中文)
localpath = r'D:/EC/EC_OMC/{}'.format(y)
if os.path.exists(localpath):
existfiles = set(os.listdir(localpath))
else:
existfiles = set()
# downloadFiles(a,b,c,d,e,f)第3个参数是过滤后留下的,第4个参数是过滤掉的
Ftp.downloadFiles(ftppath1, localpath, '级_', '', deleteset=existfiles) Ftp.ftpDisConnect()
print("\n+-------- OK!!! --------+\n")

  

安装python环境时,经常有win7老电脑(32bit)报错如下:

解决办法:

https://www.cnblogs.com/du-hong/p/10247997.html

api-ms-win-crt-process-l1-1-0.dll 丢失是因为缺少下边两个安装包

KB2999226、KB3118401更新下载:

KB2999226 微软下载链接 https://support.microsoft.com/en-us/help/2999226/update-for-universal-c-runtime-in-windows

FTP登录超时:

修改31行:ftp.connect(self.ftpserver, self.port, 30),增加, 30参数

https://docs.python.org/3/library/ftplib.html#ftplib.FTP.connect

py实现ftp的更多相关文章

  1. socketserver模块写的一个简单ftp程序

    一坨需求... 用户加密认证 允许同时多用户登录 每个用户有自己的家目录 ,且只能访问自己的家目录 对用户进行磁盘配额,每个用户的可用空间不同 允许用户在ftp server上随意切换目录 (cd) ...

  2. day-1 用python编写一个简易的FTP服务器

    从某宝上购买了一份<Python神经网络深度学习>课程,按照视频教程,用python语言,写了一个简易的FTP服务端和客户端程序,以前也用C++写过聊天程序,编程思路差不多,但是pytho ...

  3. python作业高级FTP

    转载自:https://www.cnblogs.com/sean-yao/p/7882638.html 作业需求: 1. 用户加密认证 2. 多用户同时登陆 3. 每个用户有自己的家目录且只能访问自己 ...

  4. python从FTP下载文件

    #!/usr/bin/python # -*- coding: utf-8 -*- """ FTP常用操作 """ from ftplib ...

  5. python作业高级FTP(第八周)

    作业需求: 1. 用户加密认证 2. 多用户同时登陆 3. 每个用户有自己的家目录且只能访问自己的家目录 4. 对用户进行磁盘配额.不同用户配额可不同 5. 用户可以登陆server后,可切换目录 6 ...

  6. [ python ] FTP作业进阶

    作业:开发一个支持多用户在线的FTP程序 要求: 用户加密认证 允许同时多用户登录 每个用户有自己的家目录 ,且只能访问自己的家目录 对用户进行磁盘配额,每个用户的可用空间不同 允许用户在ftp se ...

  7. [ python ] 项目一:FTP程序

    声明: 该项目参考学习地址: http://www.cnblogs.com/lianzhilei/p/5869205.html , 感谢博主分享,如有侵权,立即删除. 作业:开发一个支持多用户在线的F ...

  8. 实现支持多用户在线的FTP程序(C/S)

    1. 需求 1. 用户加密认证 2. 允许多用户登录 3. 每个用户都有自己的家目录,且只能访问自己的家目录 4. 对用户进行磁盘分配,每一个用户的可用空间可以自己设置 5. 允许用户在ftp ser ...

  9. socket实现简单的FTP

    一.开发环境 server端:centos 7  python-3.6.2 客户端:Windows 7 python-3.6.2 pycharm-2018 程序目的:1.学习使用socketserve ...

随机推荐

  1. JavaScript基础入门07

    目录 JavaScript 基础入门07 BOM window对象 Navigator对象 Screen 对象 Location对象 History 对象 JavaScript 基础入门07 BOM ...

  2. SSM到Spring Boot入门与综合实战

    一:Spring从入门到进阶 1 Spring入门 1.1 Spring IOC的底层实现原理:工厂 + 反射 + 配置文件 <bean id="us" class=&quo ...

  3. Linux C/C++基础——变量作用域

    1.局部变量 局部变量也叫auto自动变量(auto可写可不写),一般情况下代码块{}内部定义的变量都是自动变量,它有如下特点: 只有当执行到这句语句时,系统才为这个变量分配空间 在一个函数内定义,只 ...

  4. Leetcode之动态规划(DP)专题-53. 最大子序和(Maximum Subarray)

    Leetcode之动态规划(DP)专题-53. 最大子序和(Maximum Subarray) 给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和. ...

  5. 如何将其它javaweb项目变成可以成功在自己eclipse环境中运行的javaweb项目?

    说明:此文档仅适用于以下两种情况     (1)myeclipse项目需要在eclipse环境中运行     (2)eclipse项目,但是无法在自己的电脑eclipse环境中运行     注意:以下 ...

  6. Jenkins 远程部署

    参考:https://www.cnblogs.com/bookwed/p/4583033.html 准备环境: 本地开发,安装虚拟机,在虚拟机安装Linux服务器 步骤: 1.安装插件,登录到Jenk ...

  7. PTA(Basic Level)1014.福尔摩斯的约会 && PTA(Advanced Level)1061.Dating

    大侦探福尔摩斯接到一张奇怪的字条:我们约会吧! 3485djDkxh4hhGE 2984akDfkkkkggEdsb s&hgsfdk d&Hyscvnm.大侦探很快就明白了,字条上奇 ...

  8. Centos 安装Pycharm 并移动到桌面。

    版权声明:版权所有.未经同意不得转发,装载 https://blog.csdn.net/limingyue0312/article/details/81805826 1.下载pycharm软件包 网页 ...

  9. python-day9(正式学习)

    目录 深浅拷贝 拷贝 浅拷贝 深拷贝 异常处理 什么是异常 语法错误 逻辑错误 异常的种类 常用的异常 其他异常 异常处理 提前预防 事后预防 抛出异常(基本没用) 断言(调试用,现在基本上没用) 文 ...

  10. Thinkphp5.0快速入门笔记(3)

    学习来源与说明 https://www.kancloud.cn/thinkphp/thinkphp5_quickstart 测试与部署均在windows10下进行学习. 快速入门第三节 获取当前的请求 ...