在 Python 中创建 SFTP 功能
Secure Socket Shell (SSH) 是一种安全且更好的网络协议,它允许我们访问另一台计算机并通过 SHA 和加密使用密码和公钥身份验证。
SSH 文件传输协议 (SFTP) 是一种使用 SSH 的文件传输协议,优于人们以前使用的典型 FTP。
在 Python 中开发我们的应用程序可能需要文件传输协议。 我们应该使用 SFTP,它为我们提供了克服密码嗅探和中间人等攻击的默认能力,并保持我们的数据完整性。
本文向您展示如何在 Python 中使用 SFTP 来移动数据和文件。
使用 pysftp 在 Python 中创建 SFTP 功能
Python 自带 ftplib,这是一个 FTP 客户端类,带有提供不安全的 FTP 协议服务的辅助函数。 我们要使用SFTP,就需要安装第三方库,其中之一就是pysftp库。
使用 pysftp,您可以访问 SFTP 并使用安全协议来满足您的应用程序需求。 要安装 pysftp,您需要使用 pip。
pip install pysftp
另外,我们需要一个 SFTP 服务器。 对于 Windows,我们将使用 WinSCP 软件,要了解如何在 Windows PC 上设置 SFTP 服务器客户端,您可以阅读此安装指南。 但是,如果您有 SFTP 服务器,让我们开始吧。
在我们编写一些代码之前,我们将使用我们的私钥和用户名 (akinl) 和主机名 (localhost) 登录到我们的 SFTP 服务器。
现在,我们登录到根文件夹。 我们的目标是列出根目录中存在的文件和目录,并将文件复制到 SFTP 服务器,尤其是存储目录。
让我们使用 pysftp 库指定的预定义代码模板开始编码。 在代码中,我们分配了主机名、端口、用户名和私钥路径。
这些值是从您的 SFTP 服务器详细信息中获知的,私钥被复制到 python 文件的目录中。
import pysftp
sftpHostName = 'localhost'
sftpPort = 22
userName = 'akinl'
privateKeyPath = './id_rsa'
with pysftp.Connection(host=sftpHostName, port=sftpPort, username=userName, private_key=privateKeyPath, cnopts=cnOptions) as sftp:
print("Connected to SFTP server!")
上面的代码使用具有指定参数的 SFTP 连接对象 (pysftp.Connection()) 连接到 SFTP 服务器。 在 with 块中,我们在名为 sftp 的对象中建立了 SFTP 连接。
以下是代码的输出:
C:\\Python310\\lib\\site-packages\\pysftp\\__init__.py:61: UserWarning: Failed to load HostKeys from C:\\Users\\akinl\\.ssh\\known_hosts. You will need to explicitly load HostKeys (cnopts.hostkeys.load(filename)) or disableHostKey checking (cnopts.hostkeys = None).
warnings.warn(wmsg, UserWarning)
Traceback (most recent call last):
File "c:\\Users\\akinl\\Documents\\Python\\SFTP\\index.py", line 8, in <module>
with pysftp.Connection(host=sftpHostName, port=sftpPort, username=userName, private_key=privateKeyPath) as sftp:
File "C:\\Python310\\lib\\site-packages\\pysftp\\__init__.py", line 132, in __init__
self._tconnect['hostkey'] = self._cnopts.get_hostkey(host)
File "C:\\Python310\\lib\\site-packages\\pysftp\\__init__.py", line 71, in get_hostkey
raise SSHException("No hostkey for host %s found." % host)
paramiko.ssh_exception.SSHException: No hostkey for host localhost found.
Exception ignored in: <function Connection.__del__ at 0x000001F0E9656320>
Traceback (most recent call last):
File "C:\\Python310\\lib\\site-packages\\pysftp\\__init__.py", line 1013, in __del__
self.close()
File "C:\\Python310\\lib\\site-packages\\pysftp\\__init__.py", line 784, in close
if self._sftp_live:
AttributeError: 'Connection' object has no attribute '_sftp_live'
找不到主机 %s
的主机密钥是使用 pysftp 使用 SFTP 连接对象时的常见错误,当主机文件不存在时会发生这种情况。
为了处理这个问题,我们可以创建连接选项 (pysftp.CnOpts()),指定主机密钥为 None,并忽略已知主机检查。
import pysftp
sftpHostName = 'localhost'
sftpPort = 22
userName = 'akinl'
privateKeyPath = './id_rsa'
cnOptions = pysftp.CnOpts()
cnOptions.hostkeys = None
with pysftp.Connection(host=sftpHostName, port=sftpPort, username=userName, private_key=privateKeyPath, cnopts=cnOptions) as sftp:
print("SFTP server connection successful")
代码输出如下:
C:\Python310\lib\site-packages\pysftp\__init__.py:61: UserWarning: Failed to load HostKeys from C:\Users\akinl\.ssh\known_hosts. You will need to explicitly load HostKeys (cnopts.hostkeys.load(filename)) or disableHostKey checking (cnopts.hostkeys = None).
warnings.warn(wmsg, UserWarning)
SFTP server connection successful
我们遇到的唯一错误是有关禁用主机密钥检查的低级别警告。 首先,让我们更改工作目录以显示我们在 SFTP 服务器中。
import pysftp
sftpHostName = 'localhost'
sftpPort = 22
userName = 'akinl'
privateKeyPath = './id_rsa'
cnOptions = pysftp.CnOpts()
cnOptions.hostkeys = None
with pysftp.Connection(host=sftpHostName, port=sftpPort, username=userName, private_key=privateKeyPath, cnopts=cnOptions) as sftp:
print("SFTP server connection successful")
print("The current working directory is ", sftp.pwd)
sftp.cwd("./store")
print("After the cwd operation, the current working directory is ", sftp.pwd)
上面代码的输出如下:
SFTP server connection successful
The current working directory is /
After the cwd operation, the current working directory is /store.
cwd 将当前工作目录更改为其参数指定的目录。 此外,我们可以使用 listdir() 方法列出根目录和存储目录中的文件,以及
import pysftp
sftpHostName = 'localhost'
sftpPort = 22
userName = 'akinl'
privateKeyPath = './id_rsa'
cnOptions = pysftp.CnOpts()
cnOptions.hostkeys = None
with pysftp.Connection(host=sftpHostName, port=sftpPort, username=userName, private_key=privateKeyPath, cnopts=cnOptions) as sftp:
rootFiles = sftp.listdir()
storeFiles = sftp.listdir("./store")
print(rootFiles, storeFiles)
代码输出如下:
['index.txt', 'main.py', 'store'] []
如果没有传递参数,listdir()
方法会列出当前工作目录中的所有文件和目录,但如果我们提供参数,它会检查我们传递的参数中的文件。 结果是根目录有两个文件和一个目录,存储目录没有,因为文件不存在。
现在,让我们使用一些方法将一些文件移动到我们的 SFTP 服务器,put()
、put_d()
和 put_r()
。 我们将使用 put()
仅移动文件。
接下来,在与我们的 python 文件相同的目录中创建一个名为 test.txt 的文本文件,并将该文件复制到 SFTP 服务器中。
import pysftp
sftpHostName = 'localhost'
sftpPort = 22
userName = 'akinl'
privateKeyPath = './id_rsa'
cnOptions = pysftp.CnOpts()
cnOptions.hostkeys = None
with pysftp.Connection(host=sftpHostName, port=sftpPort, username=userName, private_key=privateKeyPath, cnopts=cnOptions) as sftp:
sftp.put("test.txt", preserve_mtime=True)
代码的输出:
test.txt 文件现在位于 SFTP 服务器根目录中。 现在,我们把同一个test.txt移动到store目录下,列出复制前后的文件内容。
import pysftp
sftpHostName = 'localhost'
sftpPort = 22
userName = 'akinl'
privateKeyPath = './id_rsa'
cnOptions = pysftp.CnOpts()
cnOptions.hostkeys = None
with pysftp.Connection(host=sftpHostName, port=sftpPort, username=userName, private_key=privateKeyPath, cnopts=cnOptions) as sftp:
print(sftp.listdir("./store"))
sftp.put('test.txt', preserve_mtime=True, remotepath="./store/upload.txt")
print(sftp.listdir("./store"))
上面代码的输出显示 test.txt 文件已作为 upload.txt 上传到服务器,并且在图像中可见。
[]
['upload.txt']
我们可以使用 put_d()
方法复制目录的内容。 例如,让我们创建一个包含三个文本文件(one.txt、two.txt 和 three.txt)的 SeptData 目录,并将目录内容复制到根文件夹。
但是,对于从中复制的路径,我们需要完整路径,而不是我们之前使用的相对路径。
import pysftp
sftpHostName = 'localhost'
sftpPort = 22
userName = 'akinl'
privateKeyPath = './id_rsa'
cnOptions = pysftp.CnOpts()
cnOptions.hostkeys = None
with pysftp.Connection(host=sftpHostName, port=sftpPort, username=userName, private_key=privateKeyPath, cnopts=cnOptions) as sftp:
print(sftp.listdir("./"))
sftp.put_d(r"C:\Users\akinl\Documents\Python\SFTP\SeptData",
"./", preserve_mtime=True)
print(sftp.listdir("./"))
代码的输出:
['index.txt', 'main.py', 'store', 'test.txt']
['index.txt', 'main.py', 'one.txt', 'store', 'test.txt', 'three.txt', 'two.txt']
这三个文件现在位于根目录中,如目录中的文件和目录列表所示。 因此,我们可以使用 get() 方法从 SFTP 服务器下载文件。
import pysftp
sftpHostName = 'localhost'
sftpPort = 22
userName = 'akinl'
privateKeyPath = './id_rsa'
cnOptions = pysftp.CnOpts()
cnOptions.hostkeys = None
with pysftp.Connection(host=sftpHostName, port=sftpPort, username=userName, private_key=privateKeyPath, cnopts=cnOptions) as sftp:
sftp.get("./store/upload.txt", preserve_mtime=True)
成功运行代码后,upload.txt 文件将出现在 python 文件的目录中。 您可以使用 get_d()
和 get_r()
方法获取远程目录。
使用 paramiko 在 Python 中创建 SFTP 功能
Paramiko 是一个很棒的库,它通过其类和方法为 Python 提供了 SSHv2 的直接实现。 我们可以使用其中一些方法来启动与 SFTP 服务器的连接,并通过公钥身份验证与该服务器一起工作。
要安装 paramiko,可以使用 pip 命令,如下所示:
pip install paramiko
使用上一节中的连接详细信息,我们可以执行相同的操作,从更改工作目录到从远程 SFTP 服务器获取文件。
SSHClient()
为我们创建一个新的 SSH 以连接到 SFTP 服务器,set_missing_host_key_policy()
允许我们设置连接到没有已知主机密钥的服务器的策略,而 connect()
方法创建实际连接到 SFTP 服务器。
让我们将目录更改为存储目录,并分别在 chdir、getcwd 和 listdir 的帮助下打印当前工作目录和所述目录的内容。
import paramiko
sftpHostName = 'localhost'
sftpPort = 22
userName = 'akinl'
privateKeyPath = './id_rsa'
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname=sftpHostName, port=sftpPort,
username=userName, key_filename=privateKeyPath)
sftp_client = ssh.open_sftp()
sftp_client.chdir("./store")
print(sftp_client.getcwd())
print(sftp_client.listdir())
sftp_client.close()
ssh.close()
代码的输出:
/store
['one.txt', 'three.txt', 'two.txt', 'upload.txt']
第一行包含当前工作目录,它由 chdir()
方法设置,第二行包含存储目录中的文件和目录列表。
相关文章
Python 中的 sscanf() 功能
发布时间:2023/06/20 浏览次数:180 分类:Python
-
这篇 Python 文章将使您更好地理解 sscanf() 必须提供什么以及我们如何在 Python 脚本中模仿它。Python 中的 sscanf() 功能
Python 本地服务器
发布时间:2023/06/20 浏览次数:150 分类:Python
-
本篇文章将向我们展示如何在 Python 中创建 HTTP 服务器。 在学习完本篇文章后,我们只需几行代码就可以轻松搭建一个 HTTP 服务器。
Python 中的一行 FTP 服务器
发布时间:2023/06/20 浏览次数:135 分类:Python
-
FTP 是文件传输协议的缩写。 它允许您通过计算机网络在客户端和服务器之间传输文件。使用 pyftpdlib 在 Python 中创建一行 FTP 服务器
在 Python 中检查 Argparse 的参数
发布时间:2023/06/20 浏览次数:125 分类:Python
-
本篇文章将讨论 argparse 的使用,我们将使用条件语句和 Python 中的参数名称检查 argparse 中是否存在参数。在 Python 中检查 argparse 的参数
Python 循环缓冲区
发布时间:2023/06/20 浏览次数:51 分类:Python
-
循环缓冲区是环形缓冲区的另一个名称。 Python 中的高效循环缓冲区。高效的循环缓冲区是一种允许高效插入和删除数据的数据结构。
Cron 类似 Python 中的调度程序
发布时间:2023/06/20 浏览次数:120 分类:Python
-
本篇文章将介绍调度类似于 Linux 中的 cron 作业的任务。 首先,我们将查看调度模块以在进程内调度中调度我们的作业。
通过 Crontab 执行 Python 脚本
发布时间:2023/06/20 浏览次数:57 分类:Python
-
在本文中,我们将探讨 Crontab 以及如何使用它来运行 Python 脚本。Linux/Unix/Solaris 中的 Crontab
克隆 Git 存储库的 Python 方法
发布时间:2023/06/20 浏览次数:196 分类:Python
-
让我们看看我们可以在 Python 环境中克隆 Git 存储库的不同方法。使用 PyCharm 克隆 Git 存储库
在 Python 中计算两个 GPS 点之间的距离
发布时间:2023/06/19 浏览次数:134 分类:Python
-
计算两个 GPS 点之间的距离是我们可以在 Python 框架内操作的地理和数学练习。 现在让我们看看如何使用 Python 执行此操作。在 Python 中使用 Haversine 公式计算两个 GPS 点之间的距离