You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Python中连接FTPS服务器并下载文件?证书相关问题咨询

Python连接FTPS服务器并下载文件的完整方案

优化后的完整代码示例

结合SSL安全配置与原代码的细节优化,提供更完善的实现:

import ftplib
import os
import ssl
from dateutil import parser
from datetime import datetime

def connect(host, port, user, password, verify_cert=True, client_cert=None):
    # 创建自定义SSL上下文
    context = ssl.create_default_context()
    
    if not verify_cert:
        # 测试环境可临时关闭证书验证,生产环境禁止使用此配置
        context.check_hostname = False
        context.verify_mode = ssl.CERT_NONE
    
    if client_cert:
        # 若需客户端证书,传入证书与密钥文件路径组成的元组(cert_file, key_file)
        context.load_cert_chain(*client_cert)
    
    ftp = ftplib.FTP_TLS(context=context)
    ftp.debugging = 2
    ftp.connect(host, port)
    ftp.login(user, password)
    # 将数据连接切换为TLS加密(默认仅控制连接加密)
    ftp.prot_p()
    return ftp


def retrieveFileList(ftp, ftp_paths, fileType, destinationPath, date):
    total_files = []
    timestamps = []
    # 确保目标本地目录存在
    os.makedirs(destinationPath, exist_ok=True)
    
    for path in ftp_paths:
        try:
            ftp.cwd(path)
        except ftplib.error_perm as e:
            print(f"切换远程目录失败: {e}")
            continue
        
        files = ftp.nlst(f'*{fileType}')
        for file in files:
            try:
                timestamp = ftp.voidcmd(f"MDTM {file}")[4:].strip()
                time = parser.parse(timestamp)
                parsed_time = time.strftime("%Y-%m")
                timestamps.append(parsed_time)
                
                if not date > parsed_time:
                    file_local_path = os.path.join(destinationPath, file)
                    total_files.append(file)
                    with open(file_local_path, 'wb') as f:
                        ftp.retrbinary(f'RETR {file}', f.write)
                    print(f"文件下载完成: {file}")
            except ftplib.error_perm as e:
                print(f"处理文件{file}失败: {e}")
                continue
    
    max_timestamp = max(timestamps) if timestamps else None
    return total_files, max_timestamp

疑问解答

1. 是否必须验证服务器证书?

不是强制要求,但生产环境必须开启验证。默认ftplib.FTP_TLS不会验证服务器证书,这会让连接暴露在中间人攻击风险中;测试环境(如本地Docker搭建的服务器)可临时关闭,但正式场景必须开启验证以确保连接的是真实目标服务器。

2. 是否需要创建SSL上下文并传入FTP_TLS()作为参数?

如果需要自定义SSL相关规则(比如证书验证逻辑、指定TLS版本、加载客户端证书),就需要创建并传入自定义SSL上下文。默认上下文仅提供基础加密能力,无法满足精细的安全配置需求,比如代码中通过上下文控制证书验证、加载客户端证书的逻辑。

3. 是否需要客户端证书?

完全取决于FTPS服务器的配置:

  • 多数Docker搭建的FTPS服务器(如fauria/vsftpd镜像)默认仅开启账号密码验证,无需客户端证书;
  • 若服务器配置了双向SSL认证(要求客户端提供证书证明身份),则需要准备对应客户端证书,并通过SSL上下文加载。

内容的提问来源于stack exchange,提问作者leop

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 22:45:14