使用隐式FTP over TLS从FTP服务器取文件时Python代码报错求助
解决隐式FTP over TLS的Python SSL错误问题
问题根源
你的代码存在三个核心问题,导致和FileZilla的行为不一致:
- 隐式FTPS初始化方式错误:Python的
FTP_TLS默认使用显式FTPS(端口21,先明文连接再升级SSL),但你需要的是隐式FTPS(端口990,全程SSL加密),未指定端口会导致连接模式不匹配。 - 数据连接SSL处理逻辑冲突:ftplib默认会在数据连接结束时调用
unwrap()关闭SSL,但部分隐式FTPS服务器要求数据连接全程保持SSL,这就触发了ssl.SSLEOFError错误。 - 代码中
ftps.prot_p()是无效笔误,需要删除。
修正后的代码
from ftplib import FTP_TLS import ssl import os # 创建SSL上下文,适配自签证书场景(FileZilla默认跳过此类验证) context = ssl.create_default_context() context.check_hostname = False context.verify_mode = ssl.CERT_NONE # 初始化隐式FTPS连接:指定990端口,传入自定义SSL上下文 ftps = FTP_TLS('xxx', port=990, context=context) ftps.debugging = 5 ftps.login('yyy', 'zzz') # 强制数据连接全程保持SSL保护,禁止自动关闭SSL ftps.data_channel_protect = 'P' # 获取文件列表并下载 filenames = ftps.nlst() for filename in filenames: local_filename = os.path.join('./output/', filename) # 使用with语句自动管理文件句柄 with open(local_filename, 'wb') as file: ftps.retrbinary(f'RETR {filename}', file.write) ftps.quit()
关键说明
- 端口指定:隐式FTPS标准端口是990,必须在初始化
FTP_TLS时明确指定。 - SSL上下文设置:如果服务器使用自签证书,需要禁用证书验证,否则Python会因证书不被信任而拒绝连接(FileZilla默认允许跳过此类验证)。
- 数据通道保护:设置
data_channel_protect = 'P'后,ftplib会保持数据连接的SSL加密状态,不会执行unwrap()操作,避免触发EOF错误。
内容的提问来源于stack exchange,提问作者epieters
相关产品推荐
相关产品推荐

