在SFTP服务器上查找包含Python字符串内容的文件

问题描述 投票:0回答:1

问题

在 Python 中,我的任务是在外部

(XML)
服务器上查找包含
 的文件 
SFTP

<myTag>BLA</myTag>

问题是服务器上可能有超过 5000 个文件。

有没有高效的方法?

现在的我:

  • 使用
    pysftp
    连接到
    SFTP
    服务器
  • 从那里收集所有文件名并过滤它们以仅包含 .xml
  • 使用
    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 分钟。

问题

如何优化?

先决条件

  • SFTP 位于我的域之外
  • 我没有 SSH 权限
  • 没有可行的解决方案来下载我的服务器上的所有文件
python optimization sftp pysftp
1个回答
-2
投票

使用 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

© www.soinside.com 2019 - 2024. All rights reserved.