self cleandir(self connection cwd('self connection rmd(fnameself dcount + print('directory exited'chdir into remote dir clean subdirectory chdir remote back up delete empty remote dir if __name__ ='__main__'ftp cleanall(ftp configtransfer(site='learning-python com'rdir='training'user='lutz'ftp run(cleantarget=ftp cleandirprint('done:'ftp fcount'files and'ftp dcount'directories cleaned 'besides again being recursive in order to handle arbitrarily shaped treesthe main trick employed here is to parse the output of remote directory listing the ftp nlst call used earlier gives us simple list of filenamesherewe use dir to also get file detail lines like thesec:\pp \internet\ftpftp learning-python com ftpcd training ftpdir drwxr-xr- may : drwx--- - may : -rw---- - may : -public-classes htm -rw---- - may : -public-classes html drwx--- - may : books -rw---- - may : calendar-save-aug html -rw---- - may : calendar html drwx--- - may : images -rw---- - may : index html lines omitted this output format is potentially server-specificso check this on your own server before relying on this script for this unix ispif the first character of the first item on the line is character " "the filename at the end of the line names remote directory to parsethe script simply splits on whitespace to extract parts of line notice how this scriptlike others before itmust skip the symbolic and current and parent directory names in listings to work properly for this server oddly this can vary per server as wellone of the servers used for this book' examplesfor instancedoes not include these special names in listings we can verify by running ftplib at the interactive promptas though it were portable ftp client interfacec:\pp \internet\ftppython from ftplib import ftp ftp('ftp rmi net' login('lutz''xxxxxxxx'for in nlst()[: ]print( -longmont-classes html -longmont-classes html -longmont-classes html output lines omitted no or in listings [transferring directory trees with ftplib