Python FTP 无法连接,但使用具有相同凭据的 FileZilla 等客户端工作

问题描述

我正在尝试使用 ftplib 连接到 FTP 服务器以下载一组文件。当我尝试创建连接时,我不断收到 530 User cannot log in 错误(即使使用相同的凭据成功地使用 FileZilla 登录)。

代码

from ftplib import FTP_TLS
import pandas

ftp = FTP_TLS(host="ftp._____.com",user="____",passwd="____")

ftp.login(user="______",passwd="______")
ftp.cwd("DIR/")
ftp.dir()

错误日志:

*cmd* 'USER ********'
*put* 'USER ********\r\n'
*get* '331 Password required\n'
*resP* '331 Password required'
*cmd* 'PASS ********'
*put* 'PASS ********\r\n'
*get* '230 User logged in.\n'
*resP* '230 User logged in.'
*cmd* 'CWD ______/'
*put* 'CWD ______/\r\n'
*get* '250 CWD command successful.\n'
*resP* '250 CWD command successful.'
*cmd* 'TYPE A'
*put* 'TYPE A\r\n'
*get* '200 Type set to A.\n'
*resP* '200 Type set to A.'
*cmd* 'PASV'
*put* 'PASV\r\n'
*get* '227 Entering Passive Mode (13,64,237,19,157).\n'
*resP* '227 Entering Passive Mode (13,157).'
*cmd* 'LIST'
*put* 'LIST\r\n'
*get* '534 Policy requires SSL.\n'
*resP* '534 Policy requires SSL.'
Traceback (most recent call last):
  File "xb_shipped.py",line 20,in <module>
    ftp.dir()
  File "C:\Users\main\AppData\Local\Programs\Python\python38-32\lib\ftplib.py",line 558,in dir
    self.retrlines(cmd,func)
  File "C:\Users\main\AppData\Local\Programs\Python\python38-32\lib\ftplib.py",line 451,in retrlines
    with self.transfercmd(cmd) as conn,\
  File "C:\Users\main\AppData\Local\Programs\Python\python38-32\lib\ftplib.py",line 382,in transfercmd
    return self.ntransfercmd(cmd,rest)[0]
  File "C:\Users\main\AppData\Local\Programs\Python\python38-32\lib\ftplib.py",line 781,in ntransfercmd
    conn,size = FTP.ntransfercmd(self,cmd,rest)
  File "C:\Users\main\AppData\Local\Programs\Python\python38-32\lib\ftplib.py",line 348,in ntransfercmd
    resp = self.sendcmd(cmd)
  File "C:\Users\main\AppData\Local\Programs\Python\python38-32\lib\ftplib.py",line 275,in sendcmd
    return self.getresp()
  File "C:\Users\main\AppData\Local\Programs\Python\python38-32\lib\ftplib.py",line 248,in getresp
    raise error_perm(resp)
ftplib.error_perm: 534 Policy requires SSL.

我也尝试使用此处找到的解决方案:https://stackoverflow.com/questions/55814722/cannot-list-ftp-directory-using-ftplib-but-ftp-client-works/55874794#55874794

但是由于没有使用 SSL,这个解决方案给了我一个错误

代码

from ftplib import FTP_TLS
import pandas


class SmartFTP(FTP_TLS):
    def makepasv(self):
        invalidhost,port = super(SmartFTP,self).makepasv()
        return self.host,port

ftp_server = 'ftp.____.com'
ftp = SmartFTP(ftp_server)
ftp.login(user="____",passwd="____")
ftp.cwd("DIR/")
ftp.dir()

错误

*cmd* 'AUTH TLS'
*put* 'AUTH TLS\r\n'
*get* '234 AUTH command ok. Expecting TLS Negotiation.\n'
*resP* '234 AUTH command ok. Expecting TLS Negotiation.'
*cmd* 'USER ********'
*put* 'USER ********\r\n'
*get* '331 Password required\n'
*resP* '331 Password required'
*cmd* 'PASS ********'
*put* 'PASS ********\r\n'
*get* '230 User logged in.\n'
*resP* '230 User logged in.'
*cmd* 'CWD ______/'
*put* 'CWD ______/\r\n'
*get* '250 CWD command successful.\n'
*resP* '250 CWD command successful.'
*cmd* 'TYPE A'
*put* 'TYPE A\r\n'
*get* '200 Type set to A.\n'
*resP* '200 Type set to A.'
*cmd* 'PASV'
*put* 'PASV\r\n'
*get* '227 Entering Passive Mode (13,176).\n'
*resP* '227 Entering Passive Mode (13,176).'
*cmd* 'LIST'
*put* 'LIST\r\n'
*get* '534 Policy requires SSL.\n'
*resP* '534 Policy requires SSL.'
Traceback (most recent call last):
  File "xb_shipped.py",in getresp
    raise error_perm(resp)
ftplib.error_perm: 534 Policy requires SSL.

FileZilla 日志:

Status: Resolving address of ftp.xbfulfillment.com
Status: Connecting to 13.64.237.64:21...
Status: Connection established,waiting for welcome message...
Response:   220 Microsoft FTP Service
Command:    AUTH TLS
Response:   234 AUTH command ok. Expecting TLS Negotiation.
Status: Initializing TLS...
Status: Verifying certificate...
Status: TLS connection established.
Command:    USER ********
Response:   331 Password required
Command:    PASS ********
Response:   230 User logged in.
Command:    SYST
Response:   215 Windows_NT
Command:    FEAT
Response:   211-Extended features supported:
Response:    LANG EN*
Response:    UTF8
Response:    AUTH TLS;TLS-C;SSL;TLS-P;
Response:    PBSZ
Response:    PROT C;P;
Response:    CCC
Response:    HOST
Response:    SIZE
Response:    MDTM
Response:    REST STREAM
Response:   211 END
Command:    OPTS UTF8 ON
Response:   200 OPTS UTF8 command successful - UTF8 encoding Now ON.
Command:    PBSZ 0
Response:   200 PBSZ command successful.
Command:    PROT P
Response:   200 PROT command successful.
Status: Logged in
Status: Retrieving directory listing of "/"...
Command:    CWD /
Response:   250 CWD command successful.
Command:    PWD
Response:   257 "/" is current directory.
Command:    TYPE I
Response:   200 Type set to I.
Command:    PASV
Response:   227 Entering Passive Mode (13,146).
Command:    LIST
Response:   150 opening BINARY mode data connection.
Response:   226 Transfer complete.
Status: Calculating timezone offset of server...
Command:    MDTM 021220 merch pag 2.csv
Response:   213 20201202203930
Status: Timezone offset of server is -25200 seconds.
Status: Directory listing of "/" successful

解决方法

您必须调用 FTP_TLS.prot_p 才能在数据通道上启用 TLS/SSL 加密:

ftp = FTP_TLS(ftp_server)
ftp.login(user=...user,passwd=passwd)
ftp.prot_p()

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...