Downloading a directory tree with ftplib
this should do the trick :)
import sysimport ftplibimport osfrom ftplib import FTPftp=FTP("ftp address")ftp.login("user","password")def downloadFiles(path,destination):#path & destination are str of the form "/dir/folder/something/"#path should be the abs path to the root FOLDER of the file tree to download try: ftp.cwd(path) #clone path to destination os.chdir(destination) os.mkdir(destination[0:len(destination)-1]+path) print destination[0:len(destination)-1]+path+" built" except OSError: #folder already exists at destination pass except ftplib.error_perm: #invalid entry (ensure input form: "/dir/folder/something/") print "error: could not change to "+path sys.exit("ending session") #list children: filelist=ftp.nlst() for file in filelist: try: #this will check if file is folder: ftp.cwd(path+file+"/") #if so, explore it: downloadFiles(path+file+"/",destination) except ftplib.error_perm: #not a folder with accessible content #download & return os.chdir(destination[0:len(destination)-1]+path) #possibly need a permission exception catch: ftp.retrbinary("RETR "+file, open(os.path.join(destination,file),"wb").write) print file + " downloaded" returnsource="/ftproot/folder_i_want/"dest="/systemroot/where_i_want_it/"downloadFiles(source,dest)
This is a very old question, but I had a similar need that i wanted to satisfy in a very general manner. I ended up writing my own solution that works very well for me. I've placed it on Gist here https://gist.github.com/Jwely/ad8eb800bacef9e34dd775f9b3aad987
and pasted it below in case i ever take the gist offline.
Example usage:
import ftplibftp = ftplib.FTP(mysite, username, password)download_ftp_tree(ftp, remote_dir, local_dir)
The code above will look for a directory called "remote_dir" on the ftp host, and then duplicate the directory and its entire contents into the "local_dir".It invokes the script below.
import ftplibimport osdef _is_ftp_dir(ftp_handle, name, guess_by_extension=True): """ simply determines if an item listed on the ftp server is a valid directory or not """ # if the name has a "." in the fourth to last position, its probably a file extension # this is MUCH faster than trying to set every file to a working directory, and will work 99% of time. if guess_by_extension is True: if name[-4] == '.': return False original_cwd = ftp_handle.pwd() # remember the current working directory try: ftp_handle.cwd(name) # try to set directory to new name ftp_handle.cwd(original_cwd) # set it back to what it was return True except: return Falsedef _make_parent_dir(fpath): """ ensures the parent directory of a filepath exists """ dirname = os.path.dirname(fpath) while not os.path.exists(dirname): try: os.mkdir(dirname) print("created {0}".format(dirname)) except: _make_parent_dir(dirname)def _download_ftp_file(ftp_handle, name, dest, overwrite): """ downloads a single file from an ftp server """ _make_parent_dir(dest) if not os.path.exists(dest) or overwrite is True: with open(dest, 'wb') as f: ftp_handle.retrbinary("RETR {0}".format(name), f.write) print("downloaded: {0}".format(dest)) else: print("already exists: {0}".format(dest))def _mirror_ftp_dir(ftp_handle, name, overwrite, guess_by_extension): """ replicates a directory on an ftp server recursively """ for item in ftp_handle.nlst(name): if _is_ftp_dir(ftp_handle, item): _mirror_ftp_dir(ftp_handle, item, overwrite, guess_by_extension) else: _download_ftp_file(ftp_handle, item, item, overwrite)def download_ftp_tree(ftp_handle, path, destination, overwrite=False, guess_by_extension=True): """ Downloads an entire directory tree from an ftp server to the local destination :param ftp_handle: an authenticated ftplib.FTP instance :param path: the folder on the ftp server to download :param destination: the local directory to store the copied folder :param overwrite: set to True to force re-download of all files, even if they appear to exist already :param guess_by_extension: It takes a while to explicitly check if every item is a directory or a file. if this flag is set to True, it will assume any file ending with a three character extension ".???" is a file and not a directory. Set to False if some folders may have a "." in their names -4th position. """ os.chdir(destination) _mirror_ftp_dir(ftp_handle, path, overwrite, guess_by_extension)
this is an alternative. you can try using ftputil package. You can then use it to walk the remote directories and get your files