2010-12-04 64 views
3

这是我在这里的第一篇文章,所以我很乐意成为社区的一部分。我有一个相当普通的问题要问,但这是一个相当烦人的问题,所以我希望找到答案。使用Python的FTP库检索文件

所以我想用Python的FTPLIB模块来检索一个二进制文件。

代码直接输入到解释是这样的:

>>> from ftplib import FTP 

>>> ftp = FTP('xxx.xx.xx.x') # IP of target device 

>>> ftp.login() 

>>> file = "foobar.xyz" # target file 

>>> ftp.retrbinary("RETR " + file, open('filez.txt', 'wb').write) 

虽然某些功能的工作(我可以查看设备上的所有文件,您可以通过FTP服务器应用程序的欢迎消息,甚至重命名文件),当我尝试执行上面的最后一个命令,我得到

error_perm        Traceback (most recent call last) 

/Users/user_name/<ipython console> in <module>() 

/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/ftplib.pyc in retrlines(self, cmd, callback) 
    419   if callback is None: callback = print_line 
    420   resp = self.sendcmd('TYPE A') 
--> 421   conn = self.transfercmd(cmd) 
    422   fp = conn.makefile('rb') 
    423   while 1: 

/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/ftplib.pyc in transfercmd(self, cmd, rest) 
    358  def transfercmd(self, cmd, rest=None): 
    359   """Like ntransfercmd() but returns only the socket.""" 
--> 360   return self.ntransfercmd(cmd, rest)[0] 
    361 
    362  def login(self, user = '', passwd = '', acct = ''): 

/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/ftplib.pyc in ntransfercmd(self, cmd, rest) 
    327    if rest is not None: 
    328     self.sendcmd("REST %s" % rest) 
--> 329    resp = self.sendcmd(cmd) 
    330    # Some servers apparently send a 200 reply to 

    331    # a LIST or STOR command, before the 150 reply 


/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/ftplib.pyc in sendcmd(self, cmd) 
    241   '''Send a command and return the response.''' 
    242   self.putcmd(cmd) 
--> 243   return self.getresp() 
    244 
    245  def voidcmd(self, cmd): 

/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/ftplib.pyc in getresp(self) 
    216    raise error_temp, resp 
    217   if c == '5': 
--> 218    raise error_perm, resp 
    219   raise error_proto, resp 
    220 

error_perm: 502 Command not implemented. 

我已经通过FTPLIB源看了,但我对这些各种各样的任务的编程经验是相当有限的,因为我通常使用Python的数学并没有必须工作无线之前的FTP。

所以,如果有人能给我一些解决方案的想法,这将是一个巨大的帮助。或者,如果您可以使用另一种语言提供另一种解决方案路径,这同样有帮助。

回答

8

看起来您是匿名登录(没有在ftp.login()中指定的用户名/密码),因此您会收到权限错误。尝试使用

ftp.login(user='foo', passwd='bar') 

代替。

编辑:这里是FTPLIB使用的简单例子(简单化,没有错误处理):

#!/usr/bin/env python 

from ftplib import FTP 

HOST = "localhost" 
UNAME = "foo" 
PASSWD = "bar" 
DIR = "pub" 
FILE = "test.test" 

def download_cb(block): 
    file.write(block) 

ftp = FTP(HOST) 
ftp.login(user=UNAME, passwd=PASSWD) 
ftp.cwd(DIR) 

file = open(FILE, "wb") 
ftp.retrbinary("RETR " + FILE, download_cb) 
file.close() 
ftp.close() 

注:如果retrbinary不工作,你也可以尝试设置二进制在调用它之前明确使用ftp.sendcmd("TYPE I")。这是非典型的情况,但可能有助于一些异国情调的ftp服务器。

+0

或者您可以使用wget :) – 2010-12-04 20:00:19

1

如果你的情况真的很简单,就不需要使用ftplib模块。 urllib.urlretrieve会做你需要的。例如:

import urllib 
urllib.urlretrieve('ftp://xxx.xx.xx.x/foobar.xyz', filename='filez.txt') 

注:这将是urllib.request.urlretrieve在Python 3.x中,顺便......

如果FTP服务器不是匿名的,你只需指定的用户名和密码您通常会使用网址字符串(例如ftp://user:[email protected]/path/to/file)。当然,ftp协议以纯文本格式发送密码,并且已经在脚本中存储了用户名和密码,所以由于多种原因,这是不安全的,但无论您使用哪个库,情况都是如此。

0

为我工作得很好,尝试与其他服务器(我用的是Debian的FTP服务器进行测试。):

FTP = FTP( 'XX.XX.XX.XX')”

ftp.login()

'230登录成功。'

文件=为 “robots.txt”

ftp.retrlines( “RETR” +文件,打开( 'filez.txt', 'WB')。写)

' 226文件发送OK “。