FTP多文件上传报错ftplib.error_reply:226 Transfer complete求助
ftplib.error_reply: 226 Transfer complete的问题 我来帮你排查这个问题——从报错栈和代码来看,这个错误的根源其实不是服务器返回的226本身(226是正常的传输完成响应),而是你的代码在执行storbinary时,尝试发起被动模式连接(PASV命令),却收到了这个本该在传输结束后才有的响应,说明连接状态已经异常了。
最可能的几个问题和修复方案:
1. Windows路径转义错误,导致文件无法正常读取
你的代码里打开文件的路径写法有问题:
with open('C:\myfilespath\' + filename,'rb') as f_upload:
在Python中,单引号内的\是转义字符,这里的\'会被解析成一个单引号,导致实际路径变成C:\myfilespath' + filename,显然这不是你要的路径,文件会打不开,上传的是空内容,服务器返回226,但后续的FTP操作会因为连接状态异常而报错。
修复方法:
使用原始字符串或者双反斜杠来表示Windows路径,更推荐用os.path.join自动拼接路径,避免手动处理分隔符:
import os # 用os.path.join拼接路径,兼容所有系统 local_file_path = os.path.join(r'C:\myfilespath', filename) with open(local_file_path, 'rb') as f_upload: ftp.storbinary(f'STOR {filename}', f_upload)
2. 重复关闭FTP连接的冗余操作
你的代码最后同时调用了ftp.quit()和ftp.close():
ftp.quit() ftp.close()
ftp.quit()会向服务器发送QUIT命令,正常关闭FTP连接,之后再调用ftp.close()属于冗余操作,甚至可能导致连接状态异常。如果你的脚本被反复执行,还可能导致服务器端的连接没有正常释放,积累到一定次数后出现异常。
修复方法:
只保留ftp.quit()即可,它已经会完成连接的正常关闭:
ftp.quit()
3. 循环内未处理异常,导致连接状态损坏
如果某次上传失败(比如文件不存在),没有捕获异常的话,整个脚本会崩溃;如果是部分上传后连接状态异常,后续的上传就会报错。建议在循环内添加异常处理,确保单个文件上传失败不会影响整个批量任务,必要时重新建立连接。
优化后的完整示例代码:
import ftplib import os # 配置参数 FTP_HOST = "ftp.com" FTP_USER = 'ID' FTP_PWD = 'PWD' REMOTE_DIR = "/dir" LOCAL_DIR = r'C:\myfilespath' FILE_LIST = [list] # 你的动态PDF文件名列表(不带.pdf后缀) try: # 初始化FTP连接 ftp = ftplib.FTP(FTP_HOST) ftp.login(FTP_USER, FTP_PWD) ftp.cwd(REMOTE_DIR) # 可选:开启调试模式,查看所有命令和响应 # ftp.set_debuglevel(2) for item in FILE_LIST: filename = f"{item}.pdf" local_path = os.path.join(LOCAL_DIR, filename) print(f"\n正在上传:{filename}") # 先检查本地文件是否存在 if not os.path.exists(local_path): print(f"警告:本地文件 {local_path} 不存在,跳过") continue try: with open(local_path, 'rb') as f_upload: # 可选:添加回调函数查看上传进度 def upload_progress(data): print(f"已上传 {len(data)} 字节", end='\r') ftp.storbinary(f'STOR {filename}', f_upload, callback=upload_progress) print(f"\n{filename} 上传成功") except Exception as e: print(f"\n{filename} 上传失败:{str(e)}") # 如果连接异常,重新建立连接 ftp.quit() ftp = ftplib.FTP(FTP_HOST) ftp.login(FTP_USER, FTP_PWD) ftp.cwd(REMOTE_DIR) ftp.quit() print("\n所有文件上传任务完成") except Exception as e: print(f"全局错误:{str(e)}")
额外建议
- 如果你怀疑是被动模式的问题,可以尝试切换为主动模式:
ftp.set_pasv(False),但现在大多数服务器更推荐使用被动模式(PASV)。 - 开启调试模式(
ftp.set_debuglevel(2))可以查看所有FTP命令和服务器响应,方便快速定位问题。
内容的提问来源于stack exchange,提问作者Shashi Shankar Singh

