TypeError:list indices必须是整数,而不是str,python使用collections.defaultdict(set)

时间:2016-01-25 05:32:15

标签: python python-2.7 port-scanning

我编写了一个端口扫描程序,它基本上将新的扫描结果与先前的扫描结果进行比较,然后查找更改/ got_added / got_deleted的端口。

比较端口更改的方法如下:

    def comp_ports(self,filename):
          try:
                f = open(filename)
                self.prev_report = pickle.load(f) # NmapReport

                self.old_port_dict = collections.defaultdict(set)
                for s in self.prev_report.hosts:
                     for x in s.get_open_ports():
                          self.old_port_dict[s.address].add(x)

                self.new_port_dict = collections.defaultdict(set)
                for s in self.report.hosts:
                     for x in s.get_open_ports():
                        self.new_port_dict[s.address].add(x)

                hosts = sorted(set(self.old_port_dict) | set(self.new_port_dict))

                scan_same = dict()
                scan_new = dict()
                scan_del = dict()


prev_set = set(self.prev_report.hosts)
            new_set = set(self.report.hosts)

            scan_same = prev_set & new_set
            scan_new = new_set - prev_set
            scan_del = prev_set - new_set

            print()
            print('-' * 10, 'Same')
            for host, ports in scan_same.items():
                print(host, ':')
                for port in ports:
                     print(':::', port[0], '/', port[1])

            print()
            print('*' * 10, 'Added')
            for host, ports in scan_new().items():
                print(host, ':')
                for port in ports:
                      print(':::', port[0], '/', port[1])

            print()
            print('=' * 10, 'Deleted')
            for host, ports in scan_del().items():
                print(host, ':')
                for port in ports:
                       print(':::', port[0], '/', port[1])

      except Exception as l:
             print l
             raise

根据答案,但这会抛出新的异常:

'set' object has no attribute 'items'
Traceback (most recent call last):
  File "portwatch.py", line 316, in <module>
    report.comp_ports(config.get('system','scan_directory') + '/nmap-report-old.pkl')
  File "portwatch.py", line 159, in comp_ports
    for host, ports in scan_same.items():
AttributeError: 'set' object has no attribute 'items'

我如何迭代?

3 个答案:

答案 0 :(得分:0)

问题似乎是您使用hoststr)作为self.report.hosts的索引list。您只能在str上使用dict索引,但不能在list个对象上使用。{/ p>

答案 1 :(得分:0)

考虑您发布的以下代码(引发异常的地方):

for host in hosts:
    scan_same[host] = self.prev_report.hosts[host] & self.report.hosts[host]
    scan_new[host]  = self.report.hosts[host] - self.prev_report.hosts[host]
    scan_del[host]  = self.prev_report.hosts[host] - self.report.hosts[host]

您似乎想要获取仅在两个报告中找到的公共主机集和主机集。您的代码几乎是正确的,您只是不必要地使用迭代和索引,其中set操作可以立即获得您想要的内容:

prev_set = set(self.prev_report.hosts)
new_set = set(self.report.hosts)

scan_same = prev_set & new_set
scan_new = new_set - prev_set
scan_del = prev_set - new_set

答案 2 :(得分:0)

您一直在强制将端口词典设置为集合。如果您遍历字典,它将只返回键,因此您输入一组键,很可能是字符串。

首先在词典上使用.values().items()时,您可能会更开心。