Python中解析XML的模块

经常会有这种需求,当用 nmap 扫描某个大网段的端口开放情况后,生成了xml格式的扫描报告。现在,需要将扫描的结果用excel表格呈现出来,只显示开放的端口号。

我们先来学习一下怎么解析xml文件把。

有这么一个xml文件,名为:test.xml

<books>
    <book id="01">
        <bookname>C++基础</bookname>
        <author>张三</author>
        <price>30</price>
    </book>
    <book id="02">
        <bookname>java基础</bookname>
        <author>李四</author>
        <price>40</price>
    </book>
    <book id="03">
        <bookname>Python高级</bookname>
        <author>王五</author>
        <price>50</price>
    </book>
</books>

看看我们的python代码

# -*- coding: utf-8 -*-
"""
Created on Wed Nov 13 17:57:37 2019
@author: 小谢
"""
from xml.dom.minidom import parse

doc=parse("test.xml")                    #加载xml文件
root=doc.documentElement                 #获取元素的根节点,得到一个xml.dom.minidom.Element的类
print(root,"------",type(root))
books=root.getElementsByTagName('book')  #找到root根节点下所有book子节点,得到的是一个数组
print(books[0],type(books[0]))          #book数组中每一个元素,都是xml.dom.minidom.Element的类
for book in books:                       #遍历book子节点
    print("******************BOOK******************")
    if book.hasAttribute('id'):             #判断book是否有id属性
        print('书的ID是:%s'% book.getAttribute('id'))
    ##根据标签名找到,并且输出第一个元素
    bookname=book.getElementsByTagName("bookname")[0]   #得到标签名是bookname的第一个元素,返回的是一个xml.dom.minidom.Element的类
    print("书名是:%s"%bookname.childNodes[0].data)      #输出标签名的子节点的第一个值,并转为data类型
    
    author=book.getElementsByTagName("author")[0]
    print("作者是:%s"%author.childNodes[0].data)
    
    price=book.getElementsByTagName("price")[0]
    print("价格是:%s"%price.childNodes[0].data)

运行截图

我们现在来一步一步分析代码块。

下面,让我们写一个脚本来解析nmap生成的xml格式的文件,最后生成csv格式的表格。

# -*- coding: utf-8 -*-
"""
Created on Thu Nov 14 17:51:15 2019
@author: 小谢
"""
from xml.dom.minidom import parse
import csv

doc=parse("nmap.xml")                   #先把xml文件加载进来
root=doc.documentElement                #获取元素的根节点,得到一个xml.dom.minidom.Element的类
hosts=root.getElementsByTagName('host') #找到所有是host的子节点,得到的是一个数组
f=open("nmap.csv","a",newline="") 
csv_writer=csv.writer(f)
for host in hosts:
    ip_tag=host.getElementsByTagName("address")[0]
    ip=ip_tag.getAttribute('addr')
    print("ip地址为:%s"%ip)
    ports=host.getElementsByTagName("port")        #取得端口
    for port in ports:
        portid=port.getAttribute("portid")                          #端口号
        state_tag=port.getElementsByTagName("state")[0]
        if state_tag.getAttribute("state")=="open":                   #如果端口的状态是开放的
            print("端口:%s"%portid)
            try:
                server_tag=port.getElementsByTagName("service")[0]
                server_name=server_tag.getAttribute("name")                 #服务名
                server_product=server_tag.getAttribute("product")           #服务产品
                server_version=server_tag.getAttribute("version")           #服务版本
                print("服务名:%s"%server_name)
                print("服务产品:%s"%server_product)
                print("服务版本:%s"%server_version)
                server_product_version=server_product+" "+server_version
                row=[ip,portid,server_name,server_product_version]
                csv_writer.writerow(row)
            except Exception:
                row=[ip,portid,"未识别的服务"]
                csv_writer.writerow(row)
f.close()

运行截图

发布了366 篇原创文章 · 获赞 1177 · 访问量 111万+

猜你喜欢

转载自blog.csdn.net/qq_36119192/article/details/103054321