首页 > 解决方案 > CSV Writer 写入重复行

问题描述

我是编程新手,目前正在尝试将 NMAP XML 解析为 CSV。当我打开 CSV 文件时,我看到行数超出了应有的数量。

任何人都可以告诉我我在下面的代码中做错了什么?

from libnmap.parser import NmapParser
import os
import csv

report = 'nmap_results.xml'

with open('nmap_results.csv', 'w') as output_file:
    writer = csv.writer(output_file)

    for filename in report:
        nmap_report = NmapParser.parse_fromfile(report)

        for host in nmap_report.hosts:
            row = []
            for hostname in host.hostnames:
                row.append('{}'.format(hostname))

            row.append('{}'.format(host.address))

            for serv in host.services:
                row.append(serv.port)

            writer.writerow(row)

这是CSV的输出:

yahoo.com,media-router-fp1.prod1.media.vip.gq1.yahoo.com,98.137.246.7,53,80,443
red.com,server-13-249-188-122.bos50.r.cloudfront.net,13.249.188.122,53,80,443
google.com,172.18.128.1,53,80,443
cnn.com,151.101.1.67,53
yahoo.com,media-router-fp1.prod1.media.vip.gq1.yahoo.com,98.137.246.7,53,80,443
red.com,server-13-249-188-122.bos50.r.cloudfront.net,13.249.188.122,53,80,443
google.com,172.18.128.1,53,80,443
cnn.com,151.101.1.67,53
yahoo.com,media-router-fp1.prod1.media.vip.gq1.yahoo.com,98.137.246.7,53,80,443
red.com,server-13-249-188-122.bos50.r.cloudfront.net,13.249.188.122,53,80,443
google.com,172.18.128.1,53,80,443

标签: pythoncsv

解决方案


正如刚才提到的。看起来你有太多循环。report是你的xml。每个文件名出现多少次nmap_results.xml?因为你的第一个循环说

for filename in report

好吧,如果某个filename喜欢file_A.blah出现的次数超过一次nmap_results.xml,那么您将NmapParser.parse_fromfile(report)多次在该报告名称上运行。

我假设这nmap_report是一个嵌套结构,如 JSON 或其他 XML

{hosts: [ {hostnames: [ftw, fml],
           address  : www.aol.com,
           services : [ {port: 10 },
                        {port: 20 } ] },

          {hostnames: [wtf, wow],
           address  : www.yahoo.com,
           services : [ {port: 31 },
                        {port: 41 } ] },

          {hostnames: [lol, log]
           address  : www.msn.com,
           services : [ {port: 52 },
                        {port: 62 } ] },

          {hostnames: [omg, okc],
           address  : www.url.com,
           services : [ {port: 404 }
                        {port: 88 } ] },
        ] }

上面,是我想象的结构nmap_report
-nmap_report.hosts是一个包含 4 个项目的列表。因此for x in blah.hosts一种有效的
- 每个项目(称之为 a host)都是带有键的字典hostnames,,addressservices

我假装你可以用“点”表示法调用 Python 字典。任何状况之下。结构有效。所以,通过你的循环,我们有:

    for host in nmap_report.hosts:
        row = []
        for hostname in host.hostnames:
            row.append('{}'.format(hostname))

        row.append('{}'.format(host.address))

        for serv in host.services:
            row.append(serv.port)

        writer.writerow(row)``` <--- by the way, this is a typo right? remove these '''

第1[] --> [ftw, fml] --> [ftw, fml, www.aol.com] --> [ftw, fml, www.aol.com, 10, 20]
行第2行[] --> [wtf, wow] 相同图案
第3行[] --> [lol, log] 相同图案
第4行[] --> [omg, okc] 相同图案

您应该检查是否writer.writerow(row)还添加了新行,再次检查这三个反引号 (`) 是否已从该行中删除。

根据我从您的结构中推断出的示例,您有重复的原因是因为for filename in report:多次使用相同的文件名。

您的文件名report = 'nmap_results.xml'不是唯一的。


推荐阅读