如何使用Python ftplib通过FTP下载文件

81

我有以下代码,可以轻松连接FTP服务器并打开zip文件。我想将该文件下载到本地系统。如何操作?

# Open the file for writing in binary mode
print 'Opening local file ' + filename
file = open(filename, 'wb')

# Download the file a chunk at a time
# Each chunk is sent to handleDownload
# We append the chunk to the file and then print a '.' for progress
# RETR is an FTP command

print 'Getting ' + filename
ftp.retrbinary('RETR ' + filename, handleDownload)

# Clean up time
print 'Closing file ' + filename
file.close()

9
我建议在这里使用 with 语句,它可以在完成后自动关闭文件句柄:with open(filename, "wb") as file: ftp.retrbinary("RETR " + filename, file.write) - Lekensteyn
1
FD泄漏可不是开玩笑的!顺便说一下,你可能还要将“file”重命名为“f”,因为“file”会掩盖内置的“file”。 - pnovotnak
3
如果文件是文本文件,使用 retrlines - Jossie Calderon
7个回答

79
handle = open(path.rstrip("/") + "/" + filename.lstrip("/"), 'wb')
ftp.retrbinary('RETR %s' % filename, handle.write)

5
最好加入一些上下文。正如其他人所提到的,你需要在 with 语句中调用此命令来管理文件描述符并自动关闭它! - chill_turner
正如@chill_turner所评论的那样,这甚至没有关闭本地文件。对于一个强大的示例,请参见@RdB的答案 - Martin Prikryl

38
A = filename

ftp = ftplib.FTP("IP")
ftp.login("USR Name", "Pass")
ftp.cwd("/Dir")


try:
    ftp.retrbinary("RETR " + filename ,open(A, 'wb').write)
except:
    print "Error"

在 open(i,'wb').write 中,i 是什么? - LOKE2707
@LOKE2707 是文件名,在第一行声明的。我已经更改了它。谢谢你注意到它。 - Mathias711
1
谢谢,主要是使用'try'的例子。帮了我很多! - Mateus da Silva Teixeira

17
FILENAME = 'StarWars.avi'    

with ftplib.FTP(FTP_IP, FTP_LOGIN, FTP_PASSWD) as ftp:
    ftp.cwd('movies')
    with open(FILENAME, 'wb') as f:
        ftp.retrbinary('RETR ' + FILENAME, f.write)

当然,在处理可能出现的错误时是明智的。


1
如何访问该文件?假设我在我的FTP中有一个CSV文件,我想打开并存储为数据框,我该怎么做? - LOKE2707

10

源代码托管在作者的个人域名上,PyPI上没有自述文件。过去一年中发布了几个版本,因此看起来是有维护的,+1。但是网站(文档)看起来非常老旧且有点不稳定,-1。您是否认识该作者或社区知道他?Python很大,因此任何子社区都可以。 - yzorg
嗨 - 我正在查看ftplib代码(https://github.com/python/cpython/blob/f6e5972fa984c10d47694973db1c91c6486d654a/Lib/ftplib.py#L354),但无法弄清楚如何关闭此(第354行)连接。您能否帮助我指出关闭套接字的行? - variable

10
请注意,如果您正在从FTP下载到本地计算机,请使用以下内容:
with open( filename, 'wb' ) as file :
        ftp.retrbinary('RETR %s' % filename, file.write)
否则,该脚本将在本地文件存储中而不是FTP上运行。
我自己犯了这个错误,花了几个小时的时间。
以下是脚本:
import ftplib

# Open the FTP connection
ftp = ftplib.FTP()
ftp.cwd('/where/files-are/located')


filenames = ftp.nlst()

for filename in filenames:

    with open( filename, 'wb' ) as file :
        ftp.retrbinary('RETR %s' % filename, file.write)

        file.close()

ftp.quit()

这对于较小文件的工作正常,但对于较大文件,整个过程似乎会卡住。你知道如何解决吗? - Debjyoti Banerjee

6

这是一段我用过的Python代码,虽然有些注释是用西班牙语写的,但是这个应用程序很容易理解。

# coding=utf-8

from ftplib import FTP                                                                      # Importamos la libreria ftplib desde FTP

import sys

def imprimirMensaje():                                                                      # Definimos la funcion para Imprimir el mensaje de bienvenida
    print "------------------------------------------------------"
    print "--               COMMAND LINE EXAMPLE               --"
    print "------------------------------------------------------"
    print ""
    print ">>>             Cliente FTP  en Python                "
    print ""
    print ">>> python <appname>.py <host> <port> <user> <pass>   "
    print "------------------------------------------------------"

def f(s):                                                                                   # Funcion para imprimir por pantalla los datos 
    print s

def download(j):                                                                            # Funcion para descargarnos el fichero que indiquemos según numero    
    print "Descargando=>",files[j]      
    fhandle = open(files[j], 'wb')
    ftp.retrbinary('RETR ' + files[j], fhandle.write)                                       # Imprimimos por pantalla lo que estamos descargando        #fhandle.close()
    fhandle.close()                                                     

ip          = sys.argv[1]                                                                   # Recogemos la IP       desde la linea de comandos sys.argv[1] 
puerto      = sys.argv[2]                                                                   # Recogemos el PUERTO   desde la linea de comandos sys.argv[2]
usuario     = sys.argv[3]                                                                   # Recogemos el USUARIO  desde la linea de comandos sys.argv[3]
password    = sys.argv[4]                                                                   # Recogemos el PASSWORD desde la linea de comandos sys.argv[4]


ftp = FTP(ip)                                                                               # Creamos un objeto realizando una instancia de FTP pasandole la IP
ftp.login(usuario,password)                                                                 # Asignamos al objeto ftp el usuario y la contraseña

files = ftp.nlst()                                                                          # Ponemos en una lista los directorios obtenidos del FTP

for i,v in enumerate(files,1):                                                              # Imprimimos por pantalla el listado de directorios enumerados
    print i,"->",v

print ""
i = int(raw_input("Pon un Nº para descargar el archivo or pulsa 0 para descargarlos\n"))    # Introducimos algun numero para descargar el fichero que queramos. Lo convertimos en integer

if i==0:                                                                                    # Si elegimos el valor 0 nos decargamos todos los ficheros del directorio                                                                               
    for j in range(len(files)):                                                             # Hacemos un for para la lista files y
        download(j)                                                                         # llamamos a la funcion download para descargar los ficheros
if i>0 and i<=len(files):                                                                   # Si elegimos unicamente un numero para descargarnos el elemento nos lo descargamos. Comprobamos que sea mayor de 0 y menor que la longitud de files 
    download(i-1)                                                                           # Nos descargamos i-1 por el tema que que los arrays empiezan por 0 

谢谢,这对我开始处理文件非常有帮助,即使有西班牙语的注释 :) - chuckjones242

0

如果您不仅限于使用ftplib,也可以尝试使用wget模块。这里是代码片段:

import wget
file_loc = 'http://www.website.com/foo.zip'
wget.download(file_loc)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接