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

如何在Python中通过SOCKS5代理实现FTPS文件获取?

通过SOCKS5代理访问FTPS服务器的可行方案

这个问题确实挺棘手的——毕竟Python标准库的FTP相关工具和代理工具好像天生不对付,但其实我们有办法把它们捏合在一起!下面给你两种可行的实现思路,亲测有效:

方案一:改造标准库ftplib的FTP_TLS类,结合PySocks

核心思路是:先用PySocks创建一个经过SOCKS5代理的socket,然后把这个socket替换掉ftplib.FTP_TLS默认的socket,这样就能在保持FTPS加密的同时通过代理访问服务器。

import socks
from ftplib import FTP_TLS

# 代理配置
SOCKS5_PROXY_HOST = "你的SOCKS5代理主机"
SOCKS5_PROXY_PORT = 1080  # 替换成你的代理端口
SOCKS5_PROXY_USER = "代理用户名(如果有的话)"
SOCKS5_PROXY_PW = "代理密码(如果有的话)"

# FTPS服务器配置
FTPS_HOST = "你的FTPS服务器地址"
FTPS_PORT = 990  # 隐式FTPS默认端口,显式模式用21
FTPS_USER = "FTPS用户名"
FTPS_PW = "FTPS密码"

# 1. 创建带SOCKS5代理的socket
s = socks.socksocket()
s.set_proxy(
    socks.SOCKS5,
    SOCKS5_PROXY_HOST,
    SOCKS5_PROXY_PORT,
    username=SOCKS5_PROXY_USER,
    password=SOCKS5_PROXY_PW
)

# 2. 用这个socket连接FTPS服务器
s.connect((FTPS_HOST, FTPS_PORT))

# 3. 初始化FTP_TLS并替换默认socket
ftp_tls = FTP_TLS()
ftp_tls.sock = s

# 4. 登录并启用数据通道加密(显式模式先login再调用prot_p(),隐式模式可以直接login)
ftp_tls.login(FTPS_USER, FTPS_PW)
ftp_tls.prot_p()  # 开启数据传输加密,推荐启用

# 5. 下载文件示例
remote_file = "/服务器上的文件路径/xxx.txt"
local_file = "/本地保存路径/xxx.txt"

with open(local_file, "wb") as f:
    ftp_tls.retrbinary(f"RETR {remote_file}", f.write)

# 6. 关闭连接
ftp_tls.quit()

注意事项:

  • 区分FTPS的隐式模式(端口990,连接瞬间就加密)和显式模式(端口21,先建立明文连接,再通过AUTH TLS切换加密)。如果是显式模式,登录后记得调用ftp_tls.prot_p()开启数据通道加密。
  • 如果服务器用的是自签名证书,需要跳过证书验证(生产环境不推荐),可以这样初始化FTP_TLS:
    import ssl
    ftp_tls = FTP_TLS(context=ssl._create_unverified_context())
    

方案二:用ftputil简化操作(更优雅的封装)

如果你觉得手动替换socket太麻烦,可以用ftputil这个第三方库——它对ftplib做了更友好的封装,还支持自定义socket工厂,能轻松结合PySocks实现代理访问。

首先需要安装ftputil:

pip install ftputil

然后是实现代码:

import socks
import ftputil
from ftplib import FTP_TLS

# 代理配置(同上)
SOCKS5_PROXY_HOST = "你的SOCKS5代理主机"
SOCKS5_PROXY_PORT = 1080
SOCKS5_PROXY_USER = "代理用户名"
SOCKS5_PROXY_PW = "代理密码"

# FTPS服务器配置(同上)
FTPS_HOST = "你的FTPS服务器地址"
FTPS_USER = "FTPS用户名"
FTPS_PW = "FTPS密码"
FTPS_PORT = 990

# 自定义socket工厂:返回经过SOCKS5代理的socket
def create_socks_socket(host, port):
    s = socks.socksocket()
    s.set_proxy(
        socks.SOCKS5,
        SOCKS5_PROXY_HOST,
        SOCKS5_PROXY_PORT,
        username=SOCKS5_PROXY_USER,
        password=SOCKS5_PROXY_PW
    )
    s.connect((host, port))
    return s

# 使用ftputil的FTP_TLS上下文管理器
with ftputil.FTP_TLS(
    FTPS_HOST,
    user=FTPS_USER,
    password=FTPS_PW,
    port=FTPS_PORT,
    # 传入自定义的socket工厂
    session_factory=lambda: FTP_TLS(socket_factory=create_socks_socket)
) as ftp:
    # 下载文件,用法和操作本地文件几乎一样
    ftp.download("/服务器文件路径/xxx.txt", "/本地保存路径/xxx.txt")

优点:

  • ftputil提供了类文件系统的API,操作FTP服务器更直观(比如ftp.listdir()、ftp.mkdir()等)。
  • 上下文管理器自动处理连接的开闭,不用手动调用quit()。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 07:36:24