如何使用Python的elementtree模块执行Element树解析?

时间:2014-08-21 17:04:41

标签: python elementtree nmap

所以我昨天花了大约半天的时间在交互式python命令行中试图弄清楚如何导航这个ElementTree,这让我感到困惑。根据这个网站https://docs.python.org/2/library/xml.etree.elementtree.html#module-xml.etree.ElementTree我通过

加载树
import xml.etree.ElementTree as ET
tree = ET.parse('nmaptest.xml')
root = tree.getroot()

然后我会浏览这些示例,并试图找出如何访问和遍历每个元素。只要我认为我已经开始了解它是如何拼凑在一起的,我就无法让它按照我的意愿去做。

最终,我想解析它并将相关数据转储到数据库中以便以后进行比较(或者编写一个简单比较两个xml文档的脚本,但目前超出我的能力范围。 )

我已尝试过以下内容

for host in root.iter('host'):
    print host.attrib['name']
    for address in host.iter('address'):
            print address.attrib['addr']
            for port in host.iter('port'):
                    print port.attrib['portid']

试图打印出为每个人打开的主机名,IP地址和端口......它不起作用,它几乎像主机名和地址完全不同的世界,尽管我不明白为什么会这样。我还发现只需执行

即可访问该地址
print host[1].attrib['addr']

但是,当事情被整数索引时,我无法找到任何一致性,例如上面的(因为主机[3]似乎不是像你一样的主机名,并认为它在逻辑上,主机[2]似乎是主机名,但没有.attrib或任何东西),当它们是属性时,以及当它们也是字典键时。似乎有时当我认为我找到了我正在寻找的东西,而不是看到像

这样的东西时
for host in root.iter('host'):
    print host[1].attrib

{'addrtype': 'ipv4', 'addr': '10.1.102.255'}

我会对某事做一个.attrib并看到空括号{}就像我做的那样

for host in root.iter('host'):
    print host[2].attrib

所以我根本不理解它是如何解析文档的......我不是说任何人都可以帮忙清理它或者指出一些可能对我有帮助的文档?

这是来自XML输出的示例条目......

<host starttime="1408488852" endtime="1408499159"><status state="up" reason="user-set" reason_ttl="0"/>
  <address addr="X.X.X.X" addrtype="ipv4"/>
  <hostnames>
      <hostname name="computername.domainname.com" type="PTR"/>
  </hostnames>
  <ports>
    <extraports state="filtered" count="986">
      <extrareasons reason="no-responses" count="986"/>
    </extraports>
    <port protocol="tcp" portid="X"><state state="open" reason="syn-ack" reason_ttl="127"/>    <service name="X" method="table" conf="3"/></port>
    <port protocol="tcp" portid="X"><state state="open" reason="syn-ack" reason_ttl="127"/>    <service name="X" method="table" conf="3"/></port>
    <port protocol="tcp" portid="X"><state state="open" reason="syn-ack" reason_ttl="127"/>    <service name="X" method="table" conf="3"/></port>
  </ports>
  <times srtt="332" rttvar="164" to="100000"/>
</host>    

1 个答案:

答案 0 :(得分:1)

使用此代码,

for host in root.iter('host'):
    print host.attrib['name']

您正尝试访问name元素的host属性。但是hostname元素具有该属性。

以下是获取要提取的数据的一种方法(假设有一个或多个host元素作为nmaptest.xml中公共根元素的子元素):

import xml.etree.ElementTree as ET
tree = ET.parse('nmaptest.xml')

hosts = tree.findall(".//host")

for host in hosts:
    for elem in host.iter():
        if elem.tag == "hostname":
            print elem.attrib['name']
        if elem.tag == "address":
            print elem.attrib['addr']
        if elem.tag == "port":
            print elem.attrib['portid']

输出:

X.X.X.X
computername.domainname.com
X
X
X