import os import sys from ftplib import FTP from tqdm import tqdm import time # 设置系统编码 if sys.platform == 'win32': sys.stdin.reconfigure(encoding='utf-8') sys.stdout.reconfigure(encoding='utf-8') class FTPDownloader: def __init__(self, host, user='root', passwd='123456'): """初始化FTP下载器 Args: host: FTP服务器地址 user: FTP用户名,默认为匿名用户 passwd: FTP密码,默认为匿名密码 """ self.ftp = FTP(host) self.ftp.login(user=user, passwd=passwd) self.ftp.encoding = 'utf-8' # 设置编码为UTF-8以支持中文 def download_file(self, remote_path, local_path): """下载单个文件 Args: remote_path: 远程文件路径 local_path: 本地保存路径 """ # 检查本地文件是否存在 if os.path.exists(local_path): local_size = os.path.getsize(local_path) remote_size = self.ftp.size(remote_path) # 如果本地文件大小与远程文件大小一致,则跳过下载 if local_size == remote_size: # print(f'文件已存在且大小一致,跳过下载: {local_path}') return # 可选:添加修改时间检查 # remote_mtime = self.ftp.sendcmd(f'MDTM {remote_path}')[4:] # 获取远程文件的修改时间(如果服务器支持) # remote_mtime = time.mktime(time.strptime(remote_mtime, "%Y%m%d%H%M%S")) # local_mtime = os.path.getmtime(local_path) # if local_mtime >= remote_mtime: # print(f'本地文件较新,跳过下载: {local_path}') # return file_size = self.ftp.size(remote_path) with open(local_path, 'wb') as f: with tqdm(total=file_size, desc=f'下载文件: {os.path.basename(remote_path)}', unit='B', unit_scale=True, unit_divisor=1024) as pbar: def callback(data): f.write(data) pbar.update(len(data)) self.ftp.retrbinary(f'RETR {remote_path}', callback) def download_directory(self, remote_dir='.', local_dir='.'): """递归下载整个目录 Args: remote_dir: 远程目录路径 local_dir: 本地保存目录路径 """ if not os.path.exists(local_dir): os.makedirs(local_dir) print(f'正在进入远程目录: {remote_dir}') self.ftp.cwd(remote_dir) # 获取当前目录下的所有文件和子目录 items = [] self.ftp.dir(items.append) for item in items: # 解析文件信息 tokens = item.split(maxsplit=8) name = tokens[-1] if name in ('.', '..'): continue local_path = os.path.join(local_dir, name) # 判断是目录还是文件 if item.startswith('d'): # 目录 print(f'发现子目录: {name}') self.download_directory(name, local_path) else: # 文件 self.download_file(name, local_path) self.ftp.cwd('..') # 返回上级目录 def close(self): """关闭FTP连接""" self.ftp.quit() def main(): # 设置FTP服务器信息 host = "plantgir.cn" # 移除 ftp:// 和端口号 user = 'root' passwd = '123456' # 设置本地保存目录 local_dir = 'gene' try: # 创建下载器实例 downloader = FTPDownloader(host, user, passwd) print('成功连接到FTP服务器!') # 开始下载 print('开始下载所有文件...') downloader.download_directory('.', local_dir) print('下载完成!') except Exception as e: print(f'发生错误: {str(e)}') finally: if 'downloader' in locals(): downloader.close() if __name__ == '__main__':