使用pysftp实现URL大文件下载并上传至SSH服务器的问题
解决方案:流式下载+直接上传到SSH服务器(无需本地存储)
嘿,我懂你的需求——不想把100MB的文件先存到本地,直接从源地址通过SSH传到服务器对吧?其实用pysftp结合requests就能实现流式传输,既节省本地存储空间,又能提升传输效率。下面给你详细的代码示例和关键注意点:
第一步:安装依赖库
首先确保你安装了所需的Python包,在终端运行:
pip install pysftp requests
第二步:流式传输完整代码(推荐)
这个方案不需要把整个文件下载到本地,而是一边从源URL读取数据块,一边上传到SSH服务器:
import pysftp import requests # 替换成你的实际参数 SOURCE_FILE_URL = "http://ipv4.download.thinkbroadband.com/100MB.zip" SSH_SERVER_HOST = "你的SSH服务器IP/域名" SSH_USERNAME = "你的SSH用户名" SSH_PASSWORD = "你的SSH密码" # 用密钥的话看下面的说明 REMOTE_TARGET_PATH = "/服务器上的目标文件夹/100MB.zip" # 比如 /var/uploads/100MB.zip # 配置SSH连接选项(开发环境可临时关闭主机密钥验证,生产环境务必开启) cnopts = pysftp.CnOpts() # 生产环境请替换为加载已知主机密钥,比如 cnopts.hostkeys.load("/home/your-user/.ssh/known_hosts") cnopts.hostkeys = None try: # 建立SSH连接 with pysftp.Connection( host=SSH_SERVER_HOST, username=SSH_USERNAME, password=SSH_PASSWORD, cnopts=cnopts ) as sftp: print("✅ 成功连接到SSH服务器") # 发起流式下载请求 with requests.get(SOURCE_FILE_URL, stream=True) as download_response: # 检查下载请求是否正常 download_response.raise_for_status() # 打开远程文件的写入流,开始逐块上传 with sftp.open(REMOTE_TARGET_PATH, "wb") as remote_file: # 每次读取8KB数据块,可根据网络情况调整大小(比如16384=16KB) for chunk in download_response.iter_content(chunk_size=8192): if chunk: # 过滤空数据块 remote_file.write(chunk) # 可选:打印传输进度 print(f"📤 已传输 {remote_file.tell() / 1024 / 1024:.2f} MB...", end="\r") print("\n🎉 文件传输完成!") except Exception as e: print(f"❌ 传输过程出错: {str(e)}")
额外选项:用SSH密钥登录
如果你的SSH服务器用密钥验证而不是密码,把代码里的password=SSH_PASSWORD替换成:
private_key="/本地密钥文件路径/id_rsa" # 比如 "C:/Users/YourUser/.ssh/id_rsa" 或 "/home/your-user/.ssh/id_rsa"
如果你已经下载到本地,怎么上传?
要是你已经把文件存到本地了,直接用pysftp的put方法就行:
import pysftp LOCAL_FILE_PATH = "./100MB.zip" # 你的本地文件路径 REMOTE_TARGET_PATH = "/服务器上的目标文件夹/100MB.zip" cnopts = pysftp.CnOpts() cnopts.hostkeys = None # 生产环境替换为密钥验证 with pysftp.Connection(host=SSH_SERVER_HOST, username=SSH_USERNAME, password=SSH_PASSWORD, cnopts=cnopts) as sftp: sftp.put(LOCAL_FILE_PATH, REMOTE_TARGET_PATH) print("✅ 文件上传完成!")
关键注意事项
- 主机密钥验证:生产环境绝对不要用
cnopts.hostkeys = None,一定要加载known_hosts文件,避免中间人攻击。 - Chunk大小:
chunk_size可以根据你的网络带宽调整,太大可能占用内存,太小会增加传输次数,8KB-16KB是比较均衡的选择。 - 错误处理:代码里加了
try-except和raise_for_status(),能帮你快速定位下载或连接过程中的问题。
内容的提问来源于stack exchange,提问作者Sparkflight
相关产品推荐
相关产品推荐

