Python解析复杂文本

时间:2015-09-15 20:51:59

标签: python xml-parsing python-2.6

我正在努力开发一种可以编辑XML文件下面片段的算法。任何人都可以提出想法吗?要求是将文件解析为输入,删除使用“RC4”的“密码”,并输出一个新的xml文件,只删除“RC4”密码。问题是XML文件中有多个“连接器”部分。我需要阅读所有这些,但只编辑使用端口443和特定IP地址的那个。因此,脚本需要一次解析一个Connector部分,但丢弃那些没有正确IP地址和端口的部分。试过: 1.使用ElementTree XML解析器。问题是它没有很好地输出新的XLM文件 - 这是一团糟。我需要用python 2.6来美化它。

<Connector
protocol="org.apache.coyote.http11.Http11NioProtocol"
port="443"
redirectPort="443"
executor="tomcatThreadPool"
disableUploadTimeout="true"
SSLEnabled="true"
scheme="https"
secure="true"
clientAuth="false"
sslEnabledProtocols="TLSv1,TLSv1.1,TLSv1.2"
keystoreType="JKS"
keystoreFile="tomcat.keystore"
keystorePass="XXXXX"
server="XXXX"
ciphers="TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
         TLS_DH_RSA_WITH_AES_128_CBC_SHA,
         TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
         TLS_DH_DSS_WITH_AES_128_CBC_SHA,
         TLS_RSA_WITH_AES_128_CBC_SHA,
         TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
         TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA,
         TLS_RSA_WITH_3DES_EDE_CBC_SHA,
         TLS_RSA_WITH_RC4_128_SHA"
address="192.168.10.6">

这是我的代码:

from xml.etree import ElementTree
print "[+] Checking for removal of RC4 ciphers"
file = "template.xml"

with open(file, 'rt') as f:
    tree = ElementTree.parse(f)
f.close()

for node in tree.getiterator('Connector'):
    if node.tag == 'Connector':

        address = node.attrib.get('address')
        port = node.attrib.get('port')
        if "EMSNodeMgmtIp" in address and port == "443":
            ciphers = node.attrib.get('ciphers')
            if "RC4" in ciphers:
                # If true, RC4 is enabled somewhere in the cipher suite 
                print "[+] Found RC4 enabled ciphers"

                # Find RC4 specific cipher suite string, for replacement
                elements = ciphers.split()
                search_str = ""
                for element in elements:
                    if "RC4" in element:
                        search_str = element
                        print "[+] Search removal RC4 string: %s" % search_str

                # Replace string by removing RC4 cipher
                print "[+] Removing RC4 cipher"
                replace_str = ciphers.replace(search_str,"")
                rstrip_str = replace_str.rstrip()
                if rstrip_str.endswith(','):
                    new_cipher_str = rstrip_str[:-1]
                    #print new_cipher_str

            node.set('ciphers', new_cipher_str)
tree.write('new.xml')

3 个答案:

答案 0 :(得分:1)

我提供了评论来解释发生了什么。 inb4downvote

http://localhost/bookstore/public/actualizar_paginas/local/11/46

答案 1 :(得分:0)

如果XML工具不保留原始结构和格式,请转储它们。这是一个简单的文本处理问题,您可以编写一个Python程序来处理它。

旋转文件的行;简单地回显输出除“密码”语句之外的任何内容。当你点击其中一个时:

  1. 将字符串填入变量。
  2. 将字符串拆分为列表。
  3. 删除包含“ RC4 ”的任何列表元素。
  4. 以您想要的格式打印生成的“密码”语句。
  5. 恢复正常的“读取和回显”处理。
  6. 这个算法能帮到你吗?

答案 2 :(得分:0)

以下答案。基本上必须将每个Connector部分(有4个)读入临时列表,以检查端口和地址是否正确。如果是,则通过删除密码字符串来更改密码,但仅在启用RC4密码时才进行更改。因此,代码必须一次一个地读入所有4个连接器,进入临时列表。

f = open('template.xml', 'r')
lines = f.readlines()
f.close()

new_file = open('new.xml', 'w')

tmp_list = []
connector = False
for line in lines:
    if '<Connector' in line:
        connector = True
        new_file.write(line)
    elif '</Connector>' in line:
        connector = False
        port = False
        address = False
        for a in tmp_list:
            if 'port="443"' in a:
                port = True
            elif 'address="%(EMSNodeMgmtIp)s"' in a:
                address = True
        if port and address:
            new_list = []
            count = 0
            for b in tmp_list:
                if "RC4" in b:
                    print "[+] Found RC4 cipher suite string at line index %d:  %s" % (count,b) 
                    print "[+] Removing RC4 cipher string from available cipher suites"
                    # check if RC4 cipher string ends with "
                    check = b[:-1]
                    if check.endswith('"'):
                        tmp_str = tmp_list[count-1]
                        tmp_str2 = tmp_str[:-2]
                        tmp_str2+='"\n'
                        new_list[count-1] = tmp_str2
                        replace_line = b.replace(b,"")
                        new_list.append(replace_line)
                    else:
                        replace_line = b.replace(b,"")
                        new_list.append(replace_line)
                else:
                    new_list.append(b)
                count+=1
            for c in new_list:
                new_file.write(c) 
            new_file.write('    </Connector>\n')
        else:
            # Not port and address
            for d in tmp_list:
                new_file.write(d)
            new_file.write('    </Connector>\n')
        tmp_list = []
    elif connector:
        tmp_list.append(line)
    else:
        new_file.write(line)
new_file.close()