Python FTP下载目录中的所有文件
我正在编写一个脚本,通过FTP从一个目录下载所有文件。到目前为止,我已成功连接并获取了一个文件,但我似乎无法成批工作(从目录中获取所有文件)。到目前为止,我所拥有的是:Python FTP下载目录中的所有文件,python,ftp,ftplib,Python,Ftp,Ftplib,我正在编写一个脚本,通过FTP从一个目录下载所有文件。到目前为止,我已成功连接并获取了一个文件,但我似乎无法成批工作(从目录中获取所有文件)。到目前为止,我所拥有的是: from ftplib import FTP import os, sys, os.path def handleDownload(block): file.write(block) print ".", ddir='C:\\Data\\test\\' os.chdir(ddir) ftp = FTP('te
from ftplib import FTP
import os, sys, os.path
def handleDownload(block):
file.write(block)
print ".",
ddir='C:\\Data\\test\\'
os.chdir(ddir)
ftp = FTP('test1/server/')
print 'Logging in.'
ftp.login('user1\\anon', 'pswrd20')
directory = '\\data\\test\\'
print 'Changing to ' + directory
ftp.cwd(directory)
ftp.retrlines('LIST')
print 'Accessing files'
for subdir, dirs, files in os.walk(directory):
for file in files:
full_fname = os.path.join(root, fname);
print 'Opening local file '
ftp.retrbinary('RETR C:\\Data\\test\\' + fname,
handleDownload,
open(full_fname, 'wb'));
print 'Closing file ' + filename
file.close();
ftp.close()
我敢打赌,当我运行它时,您可以看出它没有多大作用,因此任何改进建议都将不胜感激。如果这只是您想解决的问题,我可能建议使用
wget
命令:
cd c:\destination
wget --mirror --continue --no-host-directories --user=username --password=s3cr3t ftp://hostname/source/path/
如果服务器上的文件发生更改,--continue
选项可能非常危险。如果只添加文件,那么它是非常友好的
但是,如果这是一个学习练习,并且您想让您的程序正常运行,我认为您应该从以下几行开始:
directory
在大多数程序中都是远程源目录,但是os.walk()
函数无法遍历远程目录。您需要自己使用提供给函数的回调来迭代返回的文件
查看MLSD
或NLST
选项,而不是LIST
,它们可能更容易解析。(请注意,FTP实际上并没有指定列表的外观;它总是由控制台上的人来驱动,或者传输特定的文件名。因此,使用FTP列表进行巧妙操作的程序,例如在GUI中向用户显示这些列表,可能必须有大量的特殊情况代码,用于奇怪或晦涩的服务器。它们可能会(当遇到恶意文件名时,所有人都会做一些愚蠢的事情。)
你能改用吗sftp
确实有一个文件列表解析的规范,没有明文传输用户名/密码,也没有被动连接和主动连接的巨大麻烦——它只是使用单一连接,这意味着它比FTP可以跨更多防火墙工作
Edit:您需要将一个“可调用”对象传递给retrlines
函数。可调用对象可以是定义了\uuuu call\uuu
方法的类的实例,也可以是函数。虽然函数可能更容易描述,但类的实例可能更有用。(可以使用实例收集文件名,但函数必须写入全局变量。错误。)
下面是一个最简单的可调用对象:
>>> class c:
... def __call__(self, *args):
... print(args)
...
>>> f = c()
>>> f('hello')
('hello',)
>>> f('hello', 'world')
('hello', 'world')
这将创建一个新类c
,该类定义了一个实例方法\uuuuu调用\uuuuu
。这只是以一种相当愚蠢的方式打印了它的论点,但它显示了我们所谈论的是多么微不足道。:)
如果你想要更聪明的东西,它可以做如下事情:
class handle_lines:
def __init__(self):
self.lines = []
def __call__(self, *args):
self.lines << args[0]
类句柄\u行:
定义初始化(自):
self.lines=[]
定义调用(self,*args):
self.lines如果这只是您想要解决的问题,我建议使用wget
命令:
cd c:\destination
wget --mirror --continue --no-host-directories --user=username --password=s3cr3t ftp://hostname/source/path/
如果服务器上的文件发生更改,--continue
选项可能非常危险。如果只添加文件,那么它是非常友好的
但是,如果这是一个学习练习,并且您想让您的程序正常运行,我认为您应该从以下几行开始:
directory
在大多数程序中都是远程源目录,但是os.walk()
函数无法遍历远程目录。您需要自己使用提供给函数的回调来迭代返回的文件
查看MLSD
或NLST
选项,而不是LIST
,它们可能更容易解析。(请注意,FTP实际上并没有指定列表的外观;它总是由控制台上的人来驱动,或者传输特定的文件名。因此,使用FTP列表进行巧妙操作的程序,例如在GUI中向用户显示这些列表,可能必须有大量的特殊情况代码,用于奇怪或晦涩的服务器。它们可能会(当遇到恶意文件名时,所有人都会做一些愚蠢的事情。)
你能改用吗sftp
确实有一个文件列表解析的规范,没有明文传输用户名/密码,也没有被动连接和主动连接的巨大麻烦——它只是使用单一连接,这意味着它比FTP可以跨更多防火墙工作
Edit:您需要将一个“可调用”对象传递给retrlines
函数。可调用对象可以是定义了\uuuu call\uuu
方法的类的实例,也可以是函数。虽然函数可能更容易描述,但类的实例可能更有用。(可以使用实例收集文件名,但函数必须写入全局变量。错误。)
下面是一个最简单的可调用对象:
>>> class c:
... def __call__(self, *args):
... print(args)
...
>>> f = c()
>>> f('hello')
('hello',)
>>> f('hello', 'world')
('hello', 'world')
这将创建一个新类c
,该类定义了一个实例方法\uuuuu调用\uuuuu
。这只是以一种相当愚蠢的方式打印了它的论点,但它显示了我们所谈论的是多么微不足道。:)
如果你想要更聪明的东西,它可以做如下事情:
class handle_lines:
def __init__(self):
self.lines = []
def __call__(self, *args):
self.lines << args[0]
类句柄\u行:
定义初始化(自):
self.lines=[]
定义调用(self,*args):
self.lines我已经设法破解了这个问题,现在为未来的访问者发布了相关的代码:
filenames = ftp.nlst() # get filenames within the directory
print filenames
for filename in filenames:
local_filename = os.path.join('C:\\test\\', filename)
file = open(local_filename, 'wb')
ftp.retrbinary('RETR '+ filename, file.write)
file.close()
ftp.quit() # This is the “polite” way to close a connection
这对我在Python 2.5和Windows XP上起到了作用。我已经设法破解了这个问题,因此现在为未来的访问者发布了相关的代码:
filenames = ftp.nlst() # get filenames within the directory
print filenames
for filename in filenames:
local_filename = os.path.join('C:\\test\\', filename)
file = open(local_filename, 'wb')
ftp.retrbinary('RETR '+ filename, file.write)
file.close()
ftp.quit() # This is the “polite” way to close a connection
这对我在Python2.5、Windows XP上很有效。我们可以从Python程序调用dos脚本,而不是使用Python lib通过ftp下载目录。在dos脚本中,我们将使用本机ftp协议,该协议可以使用mget*.
从文件夹下载所有文件
fetch.bat
ftp -s:fetch.txt
fetch.txt
open <ipaddress>
<userid>
<password>
bin (set the mnode to binary)
cd </desired directory>
mget *.*
bye
fetch.py
import os
os.system("fetch.bat")
fetch.bat
ftp-s:fetch.txt
fetch.txt
打开
bin(将mnode设置为二进制)
光盘
mget**
再见
获取.py
导入操作系统
操作系统(“fetch.bat”)
而不是使用Python库进行ftp