经常会有这种需求,当用 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()
运行截图