在 Python 中,我的任务是在外部
(XML)
服务器上查找包含 的文件
SFTP
<myTag>BLA</myTag>
问题是服务器上可能有超过 5000 个文件。
有没有高效的方法?
pysftp
连接到 SFTP
服务器conn.getfo(file_name, file)
浏览文件以获取文件并搜索内容。import pysftp
cnopts = pysftp.CnOpts()
cnopts.hostkeys = None
conn = pysftp.Connection('...', username='...', password='..', port=22, cnopts=cnopts)
all_file_names = []
for file_attr in conn.listdir_attr(root):
filepath = f'{root}/{file_attr.filename}'.replace('//', '/')
if stat.S_ISREG(file_attr.st_mode):
all_file_names.append(filepath)
elif stat.S_ISDIR(file_attr.st_mode):
if skip_path is None or skip_path != filepath:
all_file_names = all_file_names + get_all_filenames(filepath)
for file_name in [f_name for f_name in all_file_names if f_name.endswith(tuple(['.xml']))]:
with tempfile.TemporaryFile(mode='wb+') as file:
try:
conn.getfo(file_name, file)
file.seek(0)
file.read()
# find right tag...
此代码打开每个文件大约需要 0.15 秒。因为我有 5000 个文件,所以检查所有文件需要 12.5 分钟。
如何优化?
使用 lxml 分析 XML 和 SFTP 通信的效率。 示例:
import paramiko
from lxml import etree
def find_tag_in_xml(sftp, filename, tag_name):
with sftp.file(filename, 'r') as file:
xml_content = file.read()
root = etree.fromstring(xml_content)
tag_value = root.findtext(tag_name)
if tag_value == 'BLA':
print(f"Tag {tag_name} found in {filename}")
def sftp_search(sftp, root, tag_name):
all_file_names = sftp.listdir(root)
for file_name in all_file_names:
full_path = f'{root}/{file_name}'.replace('//', '/')
if sftp.isfile(full_path) and file_name.endswith('.xml'):
find_tag_in_xml(sftp, full_path, tag_name)
elif sftp.isdir(full_path):
sftp_search(sftp, full_path, tag_name)
hostname = 'seu_servidor_sftp'
username = 'seu_nome_de_usuario'
password = 'sua_senha'
transport = paramiko.Transport((hostname, 22))
transport.connect(username=username, password=password)
sftp = paramiko.SFTPClient.from_transport(transport)
root_directory = '/caminho/para/seu/diretorio'
tag_name_to_find = 'myTag'
sftp_search(sftp, root_directory, tag_name_to_find)
sftp.close()
transport.close()
作为美国图书馆 foi paramiko e lxml para instalar ela basta fazer: pip install paramiko lxml