2010-12-04 16 views
3

Ceci est mon premier article ici, je suis donc heureux de faire partie de la communauté. J'ai une question plutôt banale à poser, mais le problème a été plutôt ennuyeux et j'espère trouver des réponses. Donc j'essaye d'utiliser le module FTPLIB de Python pour récupérer un fichier binaire.Utilisation de la bibliothèque FTP de Python pour récupérer les fichiers

Le code est entré directement dans l'interpréteur ressemblait à ceci:

>>> 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) 

Bien que certaines fonctions travaillent (je peux voir tous les fichiers sur l'appareil, le message de bienvenue de l'application serveur FTP, et même renommer fichiers), lorsque je tente d'exécuter la dernière commande ci-dessus, je reçois

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. 

Je l'ai regardé par la source de ftplib mais mon expérience de programmation avec ce genre de tâche est assez limitée, comme je l'habitude d'utiliser Python pour les mathématiques et n'ont pas eu à travailler wi le FTP avant. Donc, si quelqu'un pouvait me donner quelques idées sur une solution, ce serait une aide énorme. Alternativement, si vous pourriez suggérer un autre chemin de solution dans une langue différente qui serait également utile.

Répondre

8

Il semble que vous vous connectez anonymement (aucun nom d'utilisateur/mot de passe spécifié dans ftp.login()), vous obtenez donc une erreur d'autorisation. Essayez de vous connecter avec

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

à la place.

Edit: ici un court exemple d'utilisation de ftplib (simpliste, sans manipulation d'erreur):

#!/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() 

Note: En cas retrbinary ne fonctionne pas, vous pouvez également essayer BINARY mode explicitement avec ftp.sendcmd("TYPE I") avant de l'appeler. Ceci est un cas non-typique, mais peut aider avec certains serveurs ftp exotiques.

+0

Ou vous pouvez utiliser wget :) –

+0

Ce n'était vraiment pas ça. Les arguments anonymes par défaut ont été acceptés. S'il y avait eu un rejet de nom d'utilisateur/mot de passe, je n'aurais pas pu, par exemple, renommer les fichiers sur l'appareil. Mais j'étais. Le problème est survenu quand j'ai essayé de récupérer des fichiers. – mbm

+0

@mbm - Vous avez besoin d'un espace entre le "RETR" et le nom du fichier. Il est plus facile (de toute façon) d'utiliser 'urllib.urlretrieve' pour des cas simples comme celui-ci. (Edit: nevermind vient de réaliser que vous y avez déjà un espace ...) –

1

Si votre cas est vraiment aussi simple, il n'est pas nécessaire d'utiliser le module ftplib. urllib.urlretrieve fera ce que vous avez besoin. Par exemple:

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

Note: ce serait urllib.request.urlretrieve 3.x python, par la manière ...

Et si le serveur ftp n'est pas anonyme, vous indiquez simplement le nom d'utilisateur et mot de passe dans le url comme vous le feriez normalement (par exemple, ftp://user:[email protected]/path/to/file). Bien sûr, le protocole ftp envoie le mot de passe en texte brut, et vous avez stocké le nom d'utilisateur et le mot de passe dans le script, donc ce n'est pas sûr pour plusieurs raisons, mais c'est vrai quelle que soit la librairie utilisée.

0

fonctionne bien pour moi, essayez avec un autre serveur (je l'ai testé avec un serveur ftp debian.):

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

ftp.login()

'230 Connexion réussie.'

file = "robots.txt"

ftp.retrlines ("RETR" + fichier ouvert ('filez.txt', 'wb'). Écrire)

' 226 Fichier envoyer OK . '