Python-FTP download all files in directory
Python新手来了,所以请你忍受我。我正在编写一个脚本,通过ftp从一个目录下载所有文件。到目前为止,我已经成功地连接并获取了一个文件,但我似乎无法成批工作(从目录中获取所有文件),以下是我迄今为止所拥有的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | 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() |
我敢打赌,你可以告诉我,当我运行它的时候,它没有什么作用,所以任何改进的建议都会非常感谢
PS这不是家庭作业:DD
谢谢!!
我已经设法破解了这个问题,所以现在为未来的访问者发布相关的代码:
1 2 3 4 5 6 7 8 9 10 11 | 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、WindowsXP上对我很有用。
如果这只是你想解决的问题,我建议使用
1 2 | cd c:\destination wget --mirror --continue --no-host-directories --user=username --password=s3cr3t ftp://hostname/source/path/ |
如果服务器上的文件发生更改,
然而,如果这是一个学习练习,你想让你的计划工作,我认为你应该从这一行开始:
1 for subdir, dirs, files in os.walk(directory):
在大多数程序中,
看看
你能用
编辑:您需要将"可调用"对象传递给
下面是一个最简单的可调用对象:
1 2 3 4 5 6 7 8 9 | >>> class c: ... def __call__(self, *args): ... print(args) ... >>> f = c() >>> f('hello') ('hello',) >>> f('hello', 'world') ('hello', 'world') |
这创建了一个新的类,
如果你想要更聪明的东西,它可以这样做:
1 2 3 4 5 | class handle_lines: def __init__(self): self.lines = [] def __call__(self, *args): self.lines << args[0] |
用这个类的对象调用
我觉得这个代码有点过分了。
(从python示例https://docs.python.org/2/library/ftplib.html)在ftp.login()和设置ftp.cwd()之后,您只需使用:
1 2 3 4 5 6 7 8 9 10 11 12 | os.chdir(ddir) ls = ftp.nlst() count = len(ls) curr = 0 print"found {} files".format(count) for fn in ls: curr += 1 print 'Processing file {} ... {} of {} ...'.format(fn, curr, count) ftp.retrbinary('RETR ' + fn, open(fn, 'wb').write) ftp.quit() print"download complete." |
下载所有文件。
递归解决方案(PY 2.7):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | import os, ftplib, shutil, operator def cloneFTP((addr, user, passw), remote, local): try: ftp = ftplib.FTP(addr) ftp.login(user, passw) ftp.cwd(remote) except: try: ftp.quit() except: pass print 'Invalid input ftp data!' return False try: shutil.rmtree(local) except: pass try: os.makedirs(local) except: pass dirs = [] for filename in ftp.nlst(): try: ftp.size(filename) ftp.retrbinary('RETR '+ filename, open(os.path.join(local, filename), 'wb').write) except: dirs.append(filename) ftp.quit() res = map(lambda d: cloneFTP((addr, user, passw), os.path.join(remote, d), os.path.join(local, d)), dirs) return reduce(operator.iand, res, True) |
我是一个初学者,所以我没有有效地编写代码,但是我编写了代码并测试了它的工作状态。这是我从ftp站点下载文件和文件夹所做的,但文件结构的深度有限。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | try: a = input("Enter hostname :") b = input("Enter username :") c = input("Enter password :") from ftplib import FTP import os os.makedirs("C:\\Users\\PREM\\Desktop\\pyftp download\\ftp") os.chdir("C:\\Users\\PREM\\Desktop\\pyftp download\\ftp") ftp = FTP(host = a, user= b, passwd = c) D = ftp.nlst() for d in D: l = len(d) char = False for i in range(0,l): char = char or d[i]=="." if not char: ftp.cwd("..") ftp.cwd("..") E = ftp.nlst("%s"%(d)) ftp.cwd("%s"%(d)) try: os.makedirs("C:\\Users\\PREM\\Desktop\\pyftp download\\ftp\\%s"%(d)) except: print("you can debug if you try some more") finally: os.chdir("C:\\Users\\PREM\\Desktop\\pyftp download\\ftp\\%s"%(d)) for e in E: l1 = len(e) char1 = False for i in range(0,l1): char1 = char1 or e[i]=="." if not char1: ftp.cwd("..") ftp.cwd("..") F = ftp.nlst("%s/%s"%(d,e)) ftp.cwd("%s/%s"%(d,e)) try: os.makedirs("C:\\Users\\PREM\\Desktop\\pyftp download\\ftp\\%s\\%s"%(d,e)) except: print("you can debug if you try some more") finally: os.chdir("C:\\Users\\PREM\\Desktop\\pyftp download\\ftp\\%s\\%s"%(d,e)) for f in F: if"." in f[2:]: with open(f,'wb') as filef: ftp.retrbinary('RETR %s' %(f), filef.write) elif not"." in f: try: os.makedirs("C:\\Users\\PREM\\Desktop\\pyftp download\\ftp\\%s\\%s\\%s"%(d,e,f)) except: print("you can debug if you try some more") elif"." in e[2:]: os.chdir("C:\\Users\\PREM\\Desktop\\pyftp download\\ftp\\%s"%(d)) ftp.cwd("..") ftp.cwd("..") ftp.cwd("..") ftp.cwd("%s"%(d)) with open(e,'wb') as filee: ftp.retrbinary('RETR %s' %(e), filee.write) elif"." in d[2:]: ftp.cwd("..") ftp.cwd("..") os.chdir("C:\\Users\\PREM\\Desktop\\pyftp download\\ftp") with open(d,'wb') as filed: ftp.retrbinary('RETR %s'%(d), filed.write) ftp.close() print("Your files has been successfully downloaded and saved. Bye") except: print("try again you can do it") finally: print("code ran") |
我们可以从python程序调用dos脚本,而不是使用python lib来ftp下载目录。在DOS脚本中,我们将使用本地FTP协议,该协议可以使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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") |