各位大佬,有没有人用过python的paramiko模块通过ssh进行远程下载文件的啊,我在用此模块的时候,用的freesshd在远程电脑搭建的ssh服务,能连接上,用sftp.get方法能下载图片,但是其他文件就会报错,报错信息getAllFilePath exception: 'utf-8' codec can't decode bytes in position 90-91: invalid continuation byte,网上查了很多方法,但是还是没解决到,有几个说的改paramiko库模块,最后还是不行,跪求有时间的大佬给小白指条明路
程序代码:
import paramiko
import shutil
import os
import stat
from tkinter import *
import pymssql
import py3compat
from pymssql import _mssql
from pymssql import _pymssql
import uuid
import decimal #打包用
conn = pymssql.connect(server='',
port='',
user='',
password='',
database='',
charset='')
#实例化
cursor = conn.cursor()
def getAllFilePath(sftp, remote):
"""
获取指定sftp目录下的所有文件路径
:param sftp: 建立链接的sftp
:param remote: 指定访问的目录
:return:
"""
try:
for attr in sftp.listdir_attr(remote):
print(attr)
# 判断是否为目录
if stat.S_ISDIR(attr.st_mode):
# 计算子目录在ftp服务器上的路径
sub_remote = remote + os.sep + attr.filename
# 生成器
yield from getAllFilePath(sftp, sub_remote)
else:
# 生成器
yield remote + os.sep + attr.filename
except Exception as e:
print('getAllFilePath exception:', e)
# sftp主机
host = '192.168.0.190'
# sftp端口号
port = 22
# sftp登录用户名
username = 'YL123'
# sftp登录密码
password = '123456'
# 下载文件至本地目录
local = 'e:/sshtest/'
# 建立sftp链接
ssh = paramiko.SSHClient()
sf = paramiko.Transport((host, port))
sf.connect(username=username, password=password)
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
sftp = paramiko.SFTPClient.from_transport(sf)
def run1():
a = str(inp1.get())
a = a.replace('\n', '').replace('\r', '').strip()#去除换行和空格
if a[1].isdigit(): #如果是订单号
cursor.execute('select SalesOrderID+DrawingsOrder,SalesOrderId,DrawingsOrder from T_SalesOrder where SalesOrderID=%s', a)
else:#如果是批次号
cursor.execute('select DISTINCT SalesOrderID+DrawingsOrder,SalesOrderID,DrawingsOrder from T_SalesOrder b,T_ProductionBatch c,C_WorkOrderInfo d,T_BOM_Order a where c.planNo = d.批次号 and a.orderid = d.订单号 and a.salesOrder_id = b.id and d.批次号=%s',a)
row = cursor.fetchone()
while row:
filename = str(row[2])
orderid = str(row[1])
# sftp指定目录
remote = '/freeSSHd/%s' % (orderid)
# 获取sftp指定目录下的所有文件路径
filenames = getAllFilePath(sftp, remote)
# 下载所有文件
for fn in filenames:
filename = os.path.split(fn)[-1]
sftp.get(fn, local + os.sep + filename)
# with sftp.open(filename, 'rb') as fp:
# shutil.copyfileobj(fp, open(local + os.sep + filename, 'wb'))
s = '-------------------\n%s\n' % (fn)
txt.insert(END, s) # 追加显示运算结果
inp1.delete(0, END) # 清空输入
row = cursor.fetchone()
root = Tk()
root.geometry('460x240')
root.title('IT')
# 布置界面
lb1 = Label(root, text='请输入单号或者批次号')
lb1.place(relx=0.1, rely=0.1, relwidth=0.8, relheight=0.1)
inp1 = Entry(root)
inp1.place(relx=0.3, rely=0.2, relwidth=0.4, relheight=0.1)
# 方法-直接调用 run1()
btn1 = Button(root, text='下载', command=run1)
btn1.place(relx=0.35, rely=0.4, relwidth=0.3, relheight=0.1)
# 在窗体垂直自上而下位置60%处起,布局相对窗体高度40%高的文本框
txt = Text(root)
txt.place(rely=0.6, relheight=0.4)
root.mainloop()
# 关闭sftp
sf.close()
import shutil
import os
import stat
from tkinter import *
import pymssql
import py3compat
from pymssql import _mssql
from pymssql import _pymssql
import uuid
import decimal #打包用
conn = pymssql.connect(server='',
port='',
user='',
password='',
database='',
charset='')
#实例化
cursor = conn.cursor()
def getAllFilePath(sftp, remote):
"""
获取指定sftp目录下的所有文件路径
:param sftp: 建立链接的sftp
:param remote: 指定访问的目录
:return:
"""
try:
for attr in sftp.listdir_attr(remote):
print(attr)
# 判断是否为目录
if stat.S_ISDIR(attr.st_mode):
# 计算子目录在ftp服务器上的路径
sub_remote = remote + os.sep + attr.filename
# 生成器
yield from getAllFilePath(sftp, sub_remote)
else:
# 生成器
yield remote + os.sep + attr.filename
except Exception as e:
print('getAllFilePath exception:', e)
# sftp主机
host = '192.168.0.190'
# sftp端口号
port = 22
# sftp登录用户名
username = 'YL123'
# sftp登录密码
password = '123456'
# 下载文件至本地目录
local = 'e:/sshtest/'
# 建立sftp链接
ssh = paramiko.SSHClient()
sf = paramiko.Transport((host, port))
sf.connect(username=username, password=password)
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
sftp = paramiko.SFTPClient.from_transport(sf)
def run1():
a = str(inp1.get())
a = a.replace('\n', '').replace('\r', '').strip()#去除换行和空格
if a[1].isdigit(): #如果是订单号
cursor.execute('select SalesOrderID+DrawingsOrder,SalesOrderId,DrawingsOrder from T_SalesOrder where SalesOrderID=%s', a)
else:#如果是批次号
cursor.execute('select DISTINCT SalesOrderID+DrawingsOrder,SalesOrderID,DrawingsOrder from T_SalesOrder b,T_ProductionBatch c,C_WorkOrderInfo d,T_BOM_Order a where c.planNo = d.批次号 and a.orderid = d.订单号 and a.salesOrder_id = b.id and d.批次号=%s',a)
row = cursor.fetchone()
while row:
filename = str(row[2])
orderid = str(row[1])
# sftp指定目录
remote = '/freeSSHd/%s' % (orderid)
# 获取sftp指定目录下的所有文件路径
filenames = getAllFilePath(sftp, remote)
# 下载所有文件
for fn in filenames:
filename = os.path.split(fn)[-1]
sftp.get(fn, local + os.sep + filename)
# with sftp.open(filename, 'rb') as fp:
# shutil.copyfileobj(fp, open(local + os.sep + filename, 'wb'))
s = '-------------------\n%s\n' % (fn)
txt.insert(END, s) # 追加显示运算结果
inp1.delete(0, END) # 清空输入
row = cursor.fetchone()
root = Tk()
root.geometry('460x240')
root.title('IT')
# 布置界面
lb1 = Label(root, text='请输入单号或者批次号')
lb1.place(relx=0.1, rely=0.1, relwidth=0.8, relheight=0.1)
inp1 = Entry(root)
inp1.place(relx=0.3, rely=0.2, relwidth=0.4, relheight=0.1)
# 方法-直接调用 run1()
btn1 = Button(root, text='下载', command=run1)
btn1.place(relx=0.35, rely=0.4, relwidth=0.3, relheight=0.1)
# 在窗体垂直自上而下位置60%处起,布局相对窗体高度40%高的文本框
txt = Text(root)
txt.place(rely=0.6, relheight=0.4)
root.mainloop()
# 关闭sftp
sf.close()