如何用Paramiko从SFTP服务器下载今日新增的所有文件?
解决SFTP服务器每日新增文件批量下载问题
完整可运行代码
import paramiko import os import datetime import time # 配置信息 SFTP_HOST = "sftp.xxxxx.com" SFTP_PORT = 22 SFTP_USER = "yyyyy" SFTP_PASS = "bbbbbb" REMOTE_DIR = "/out" # SFTP目标目录 LOCAL_DIR = "C:/data_transfered" # 本地保存目录 FILE_PREFIX = "JOY" # 需要筛选的文件前缀 def download_todays_files(): # 确保本地目录存在,不存在则创建 if not os.path.exists(LOCAL_DIR): os.makedirs(LOCAL_DIR) # 计算今日0点的UTC时间戳,避免时区差异导致筛选错误 today = datetime.datetime.now(datetime.timezone.utc).date() today_start = datetime.datetime.combine(today, datetime.time.min, tzinfo=datetime.timezone.utc) today_start_timestamp = time.mktime(today_start.timetuple()) try: # 自动管理SFTP连接,无需手动关闭 with paramiko.Transport((SFTP_HOST, SFTP_PORT)) as transport: transport.connect(username=SFTP_USER, password=SFTP_PASS) with paramiko.SFTPClient.from_transport(transport) as sftp: # 遍历远程目录下的所有文件属性 for file_attr in sftp.listdir_attr(REMOTE_DIR): filename = file_attr.filename # 筛选条件:前缀匹配 + 修改时间在今日范围内 if filename.startswith(FILE_PREFIX) and file_attr.st_mtime >= today_start_timestamp: remote_file_full_path = os.path.join(REMOTE_DIR, filename) local_file_full_path = os.path.join(LOCAL_DIR, filename) print(f"开始下载: {filename}") sftp.get(remote_file_full_path, local_file_full_path) print(f"{filename} 下载完成") print("今日新增文件下载任务全部完成") except Exception as e: print(f"下载出错: {str(e)}") if __name__ == "__main__": download_todays_files()
核心要点说明
1. 路径规范处理
- 远程路径:通过
REMOTE_DIR指定SFTP上的目标目录,用os.path.join自动拼接完整文件路径,避免手动写分隔符导致的跨平台或格式错误。 - 本地路径:先检查本地目录是否存在,不存在则自动创建;同样用
os.path.join拼接本地保存路径,确保文件被正确存入指定目录。
2. 今日文件精准筛选
- 使用UTC时区计算今日起始时间,避免本地时区与SFTP服务器时区不一致导致的筛选偏差。
- 利用
file_attr.st_mtime(文件修改时间戳)与今日起始时间戳对比,精准筛选当日新增/修改的文件。
3. 连接安全管理
- 用
with语句管理Transport和SFTPClient,代码块结束后自动关闭连接,避免资源泄漏。
4. 自动化执行配置
- 将代码保存为
sftp_download.py,Windows下可创建批处理文件(daily_download.bat):
@echo off python "C:\你的代码路径\sftp_download.py"
- 通过Windows任务计划程序设置每日定时执行该批处理;Linux/macOS可通过
crontab添加定时任务。
常见问题排查
- 连接失败:检查SFTP地址、端口、账号密码是否正确,确认本地网络可访问服务器。
- 文件下载失败:检查远程文件是否存在、本地目录是否有写入权限、文件是否被服务器占用。
- 时区偏差:若服务器使用本地时区而非UTC,可调整
today_start的时区设置,改用服务器所在时区计算起始时间。
内容的提问来源于stack exchange,提问作者refokaj
相关产品推荐
相关产品推荐

