Использование библиотеки FTP Python для получения файлов - PullRequest
3 голосов
/ 04 декабря 2010

это мой первый пост здесь, так что я рад быть частью сообщества. У меня есть довольно приземленный вопрос, но это была довольно раздражающая проблема, поэтому я надеюсь найти ответы.

Итак, я пытаюсь использовать модуль 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.

Так что, если бы кто-нибудь мог дать мне несколько идей относительно решения, это было бы огромной помощью. В качестве альтернативы, если бы вы могли предложить другой путь решения на другом языке, который был бы одинаково полезным.

Ответы [ 3 ]

8 голосов
/ 04 декабря 2010

Похоже, вы входите в систему анонимно (имя пользователя / пароль не указаны в 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-серверами.

1 голос
/ 04 декабря 2010

Если ваш случай действительно так прост, нет необходимости использовать модуль ftplib.urllib.urlretrieve будет делать то, что вам нужно.Например:

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

Примечание: это будет urllib.request.urlretrieve в Python 3.x, кстати ...

И если сервер FTP не 't анонимно, вы просто указываете имя пользователя и пароль в строке URL, как обычно (например, ftp://user:password@server/path/to/file).Конечно, протокол ftp отправляет пароль в виде простого текста, и вы сохранили имя пользователя и пароль в сценарии, так что это небезопасно по нескольким причинам, но это верно независимо от того, какую библиотеку вы используете.

0 голосов
/ 04 декабря 2010

Работает нормально для меня, попробуйте другой сервер (я тестировал на ftp-сервере debian.):

ftp = FTP ('xx.xx.xx.xx') '

ftp.login ()

'230 Вход выполнен успешно.'

file = "robots.txt"

ftp.retrlines ("RETR" + файл, open ('filez.txt', 'wb'). write)

'226 Файл отправлен OK.'

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...