【发布时间】:2017-10-18 20:34:01
【问题描述】:
我不知道如何使用 ftplib 查看 FTP 站点的文件内容。
我可以用WinSCP很好地连接到FTP站点,并且可以看到根目录下的6个文件。
在 Python 3.4 中,我使用以下代码:
from ftplib import FTP_TLS
ftps = FTP_TLS(timeout=100)
ftps.connect(ipAddress, 21)
ftps.auth()
ftps.prot_p()
ftps.login('username', 'password')
产生:
Out[72]: '230 User logged in.'
然后我可以运行这个:
ftps.pwd()
...我看到我在根目录中:
Out[73]: '/'
一切似乎都是肉汁。但是,当我尝试使用 ftps.dir() 或 ftps.retrlines('NLST') 或我尝试过的任何其他方法查看目录中的内容时,我会超时:
TimeoutError: [WinError 10060] A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond
我在 Google 上四处搜索,发现有几个人说这可能是“被动与主动”连接设置问题。然而,我问 FTP 的管理员是被动的还是主动的,他表现得难以置信,只是说,“这不是 SFTP。它是明确的 FTP over TLS!”
我对此一无所知。我只是想使用 ftplib(或任何其他软件包!)连接到他的 FTP 并下载一些文件。
我错过了什么??
编辑: 我刚刚发现 WinSCP 正在使用被动模式,所以这似乎是可行的。据我了解,ftplib 默认情况下是被动的,但我还是继续将标志设置为 true。这什么也没做,我仍然遇到同样的问题。
我还检查了我的防火墙(抓住稻草),它已完全关闭,所以那里应该没有问题。
我还尝试使用 '.sendcmd()' 方法发送显式命令,该方法似乎能够发送命令,但不会获取任何响应(或者它看不到响应)。
有什么原因可以让我看到我所在的目录,但看不到任何其他数据吗?我显然已连接并与服务器交谈,看起来目录对我可用和可见意味着数据可以来回传输。数据是否可能以某种 ftplib 无法识别的方式返回?关于我应该从哪里开始解决这个问题的任何想法?
最后,再次,似乎一切都设置正确,因为我可以在 WinSCP 中看到一切正常。我应该检查哪些设置来与 ftplib 进行比较?
编辑 2:
根据要求,我设置了调试级别(感谢此提示),以下是输出:
ftps = FTP_TLS(timeout=15)
ftps.set_debuglevel(2)
ftps.connect(ipAddress, 21)
ftps.set_pasv(True)
ftps.auth()
ftps.prot_p()
ftps.login('username', 'password')
ftps.retrlines('NLST')
*get* '220 Microsoft FTP Service\n'
*resp* '220 Microsoft FTP Service'
*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* 'PBSZ 0'
*put* 'PBSZ 0\r\n'
*get* '200 PBSZ command successful.\n'
*resp* '200 PBSZ command successful.'
*cmd* 'PROT P'
*put* 'PROT P\r\n'
*get* '200 PROT command successful.\n'
*resp* '200 PROT command successful.'
*cmd* 'USER username'
*put* 'USER username\r\n'
*get* '331 Password required for username.\n'
*resp* '331 Password required for username.'
*cmd* 'PASS ****************'
*put* 'PASS ****************\r\n'
*get* '230 User logged in.\n'
*resp* '230 User logged in.'
*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 (10,19,1,137,195,128).\n'
*resp* '227 Entering Passive Mode (10,19,1,137,195,128).'
Traceback (most recent call last):
File "<ipython-input-13-a79eb3c23dc5>", line 8, in <module>
ftps.retrlines('NLST')
File "C:\Anaconda3\lib\ftplib.py", line 467, in retrlines
with self.transfercmd(cmd) as conn,
File "C:\Anaconda3\lib\ftplib.py", line 398, in transfercmd
return self.ntransfercmd(cmd, rest)[0]
File "C:\Anaconda3\lib\ftplib.py", line 793, in ntransfercmd
conn, size = FTP.ntransfercmd(self, cmd, rest)
File "C:\Anaconda3\lib\ftplib.py", line 360, in ntransfercmd
source_address=self.source_address)
File "C:\Anaconda3\lib\socket.py", line 516, in create_connection
raise err
File "C:\Anaconda3\lib\socket.py", line 507, in create_connection
sock.connect(sa)
timeout: timed out
编辑 3:
我尝试将被动标志设置为 false,但是当我请求文件时,我得到以下信息:
ftps.retrlines('NLST')
*cmd* 'TYPE A'
*put* 'TYPE A\r\n'
*get* '200 Type set to A.\n'
*resp* '200 Type set to A.'
*cmd* 'PORT 10,1,10,100,223,39'
*put* 'PORT 10,1,10,100,223,39\r\n'
*get* '501 Server cannot accept argument.\n'
*resp* '501 Server cannot accept argument.'
编辑 4:
我在 WinSCP 上启用了登录,看起来乐于助人的 Steffen Ullrich 是对的!这是在 WinSCP 的日志中:
< 2017-05-19 08:44:27.880 227 Entering Passive Mode (10,19,1,137,195,139).
< 2017-05-19 08:44:27.880 Server sent passive reply with unroutable address 10.19.1.137, using host address instead.
那么,我如何让 ftplib 做同样的事情呢?
编辑 5:
找到THIS - 这只是重写源代码以使其看起来适合主机。还有其他人有更简单、侵入性更小/可能破坏性的方法吗?
作为第二个选项,由于管理员似乎不太擅长鼻烟,有什么明确的我可以告诉他去主机做以使这项工作更好(即 - 被动返回正确的 IP)?
【问题讨论】:
-
如果你引用的是真的,那么管理员是毫无头绪的,至少在这方面是这样。 SFTP 是通过 SSH 传输文件,并且没有被动与主动模式。您正在使用 FTPS,并且有类似于普通 FTP 的被动和主动。但是,使用的内容由客户端而不是服务器控制。这意味着您不需要管理员,但需要在代码中使用FTP.set_pasv。
-
我试过这个,但没有骰子。我检查了 WinSCP(效果很好),它被设置为被动模式。我在 ftplib 中设置了被动标志,但问题没有解决。
-
请在 ftplib 中 enable debugging 并将输出添加到您的问题中(不在评论中)。可能是服务器在对 PASV 的响应中包含错误的 IP 地址,这通常是防火墙后面的 FTP 服务器的情况。有些 FTP 客户端可以解决这种损坏的配置,有些则不能。
-
感谢您将我指向调试,非常感谢。如何查找此错误 IP?我可以在 ftplib 中解决它吗?请参阅上面的调试。
-
是的,看起来你是对的(见编辑 4)。服务器正在回复被动模式的 no bueno IP。 WinSCP 似乎能够解决它。我可以强制 ftplib 做同样的事情吗?