TypeError: list indices must be integers, not str , python using collections.defaultdict(set)

TypeError: list indices must be integers, not str , python using collections.defaultdict(set)

我写了一个端口扫描器,基本上是将新的扫描结果与以前的扫描结果进行比较,然后找到哪些端口 changed/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'

如何迭代?

问题似乎是您正在使用 host(一个 str)作为您的 self.report.hosts 的索引,它是一个 list。您只能在 dict 上使用 str 索引,而不能在 list 对象上使用。

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

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]

您似乎想要获取常见主机集和仅在两个报告中的每一个中找到的主机集。您的代码几乎是正确的,您只是不必要地使用了迭代和索引,其中集合操作立即为您提供了您想要的内容:

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

你一直在强制端口字典成集合。如果你遍历字典,它只会 return 键,所以你输入一组键,很可能是字符串。

如果先在听写上使用 .values().items(),您可能会更开心。