工作中有一个需求是连接sftp去上传和下载文件。最近因为疫情原因,要居家办公。前几天连接VPN到公司网络发现不能连接sftp,经过排查发现是sftp限制了连接的IP。公司的外网IP和VPN连入公司的IP不一致。
研究了一下问题,可以通过公司的电脑进行跳转。
即连入VPN后然后远端桌面登录公司内的电脑进行操作。但是这样也存在一个问题,公司的电脑不是共用的,如果登录了,会导致密码泄露或者资料被误删的情况。偶尔的使用是可以的。如果多人或者频繁使用不够方便。
采用共享文件夹的方式,将需要上传的文件和下载下来的文件放入共享文件夹。然后共享文件夹进行网域内权限控制。可以实现多人访问。那么接下来要实现的就是自动下载和上传文件
对于sftp连接,在网上搜了一下,python使用比较多的是paramiko
。引用起来也比较方便。
它功能还是比较多,这里主要是建立sftp连接以及调用他的put()
和get()
方法。
使用Transport
连接Host
和Port
,然后传入username
和port
.
接下来调用SFTPClient初始化
sf = paramiko.Transport((host,port))
sf.connect(username = username,password = password)
sftp = paramiko.SFTPClient.from_transport(sf)
get()
介绍使用方法是 sftp.get(remote+f,local+f)
,remote
为ftp连接的路径,local
为本机路径。f
为文件名。因为要循环文件,所以使用连接符连接路径和文件名。当然也可以直接放入文件完整路径。
put()
介绍sftp.put(local,remote)
分别传入本地文件路径和上传的文件路径。
rename(remote+f,backup+f)
介绍
当我们在ftp下载完文件,往往需要移入backup文件夹。sftp操作不像本机可以直接移动。但是如果删除再上传到backup里面好像又太麻烦。rename
则可以满足文件移动的需求。针对路径和账号密码已隐藏
mport paramiko
import os
## 引用企业微信消息推送
from WorkWeChat import WeChat
def sftp_upload(host,port,username,password,local,remote):
sf = paramiko.Transport((host,port))
sf.connect(username = username,password = password)
sftp = paramiko.SFTPClient.from_transport(sf)
try:
sftp.put(local,remote)#上传文件
os.remove(local)
return(f"upload {local} ok")
except Exception as e:
return(f"upload error {e}")
sf.close()
def sftp_download(host,port,username,password,local,remote):
backup=remote+"Backup/"
sf = paramiko.Transport((host,port))
sf.connect(username = username,password = password)
sftp = paramiko.SFTPClient.from_transport(sf)
print(username)
print(sftp.listdir(remote))
try:
for f in sftp.listdir(remote):#遍历远程目录
if "csv" in f:
print(remote+f)
sftp.get(remote+f,local+f)#下载目录中文件
sftp.rename(remote+f,backup+f)
return("download file " + f + "in remote")
except Exception as e:
print('download exception:',e)
return ("error")
sf.close()
if __name__=="__main__":
qywx=WeChat()
usrlist=('aaaa','bbbb')#微信推送人员名单
consumptiondir = ""
keyremote="/XXXX/"
host = "192.168.0.1"#远端地址
port = 22
local="E:\\local\\" #本机路径
consumlocal="E:\\XXX\XXXX\\"#上传文件路径
username = ("XYZ","ABC","123")# 多账号上传
password = "8888888"
wemsg="####"
for dirpath,dirname,filename in os.walk(consumlocal):
for f in filename:
accountid=5
#针对不同文件名引用不同的账号登录
if "XYZ" in f:
accountid=0
elif "ABC" in f:
accountid=2
elif "123" in f:
accountid=1
uploadmes=sftp_upload(host,port,username[accountid],password,consumlocal+f,consumptiondir+f)
wemsg=wemsg+f'\r\n\r\n- {uploadmes}'
if len(wemsg)>4:
qywx.send_message(wemsg,*usrlist)
downmsg="####"
for user in username:
downloadmsg= sftp_download(host,port,user,password,local,keyremote)
downmsg=downmsg+f' \r\n\r\n- {downloadmsg}'
#针对空消息不推送
if len(downmsg)>37:
qywx.send_message(downmsg,*usrlist)