添加节点&通过networkx和使用python在图形中的边缘

时间:2015-07-05 12:41:49

标签: python graph networkx scapy

我需要创建一个IP地址图并在它们之间标记边缘,我为此编写了下面的代码。列表,parseOutput()的内容看起来像这样:

onload

当我运行此代码时,出现以下错误:

('172.16.254.128', '216.58.208.206')
('216.58.208.206', '172.16.254.128')
('172.16.254.128', '216.58.208.226')
('216.58.208.226', '172.16.254.128')
('172.16.254.128', '8.8.8.8')
('8.8.8.8', '172.16.254.128')
('172.16.254.128', '216.58.208.227')
('172.16.254.128', '216.58.208.227')
('216.58.208.227', '172.16.254.128')
('172.16.254.128', '216.58.208.227')
('172.16.254.128', '216.58.208.227')
...
Traceback (most recent call last):
  File "test.py", line 40, in <module>
    g.add_nodes_from(nodeList)
  File "/usr/local/lib/python2.7/dist-packages/networkx/classes/graph.py", line 429, in add_nodes_from
    nn,ndict = n
ValueError: need more than 0 values to unpack

我甚至都不知道自己做错了什么。文档并没有说明多少 所有在线示例似乎都使用与我的代码相同的语法编写。

1 个答案:

答案 0 :(得分:4)

您看到的问题是由

引起的
IPList = [[] for i in range (20)]

这导致parsePcap()len(pkts)小于20时在结尾处返回带有空列表或列表的序列列表:

parseOutput = [
('172.16.254.128', '216.58.208.206'),
...
('172.16.254.128', '216.58.208.227'),
[],  #<---------------- This is causing the problem 
]

parseOutput传递给g.add_nodes_from时, 您收到回溯错误消息:

File "/usr/local/lib/python2.7/dist-packages/networkx/classes/graph.py", line 429, in add_nodes_from
  nn,ndict = n
ValueError: need more than 0 values to unpack

回想起来,如果你仔细考虑错误信息 你可以看到它告诉你n有0个值要解包。这样做 感觉节点n是否为空列表:

In [136]: nn, ndict = []
ValueError: need more than 0 values to unpack

空列表来自parseOutput

而不是预先分配固定大小的列表:

IPList = [[] for i in range (20)]

在Python中执行此操作的首选方法是使用append方法:

def parsePcap():
    IPList = []
    for pkt in pkts:
        if pkt.haslayer(IP):
            x = pkt.getlayer(IP).src
            y = pkt.getlayer(IP).dst
            IPList.append((x, y))
    return IPList

这更容易,更易读,因为您不需要对索引大惊小怪 数字并递增计数器变量。而且,它允许你处理 pkts中的任意数量的项目,而不必首先知道其长度 pkts

需要修复的另一件事是nodeList通常不是。{ 与edgeList相同。

如果您要宣布nodeListnodeList应该是可迭代的IP地址和edgeList 应该是一个可迭代的元组,如parseOutput

nodeList = set([item for pair in parseOutput for item in pair])
print(nodeList)
# set(['216.58.208.206', '216.58.208.227', '172.16.254.128',
#  '216.58.208.226', '8.8.8.8'])

但是,由于edgeList中也提到了所有节点,因此您可以省略声明节点并使用

edgeList = parseOutput
g.add_edges_from(edgeList)

g.add_edges_from将隐式添加节点。

import matplotlib.pyplot as plt
import networkx as nx

parseOutput = [
('172.16.254.128', '216.58.208.206'),
('216.58.208.206', '172.16.254.128'),
('172.16.254.128', '216.58.208.226'),
('216.58.208.226', '172.16.254.128'),
('172.16.254.128', '8.8.8.8'),
('8.8.8.8', '172.16.254.128'),
('172.16.254.128', '216.58.208.227'),
('172.16.254.128', '216.58.208.227'),
('216.58.208.227', '172.16.254.128'),
('172.16.254.128', '216.58.208.227'),
('172.16.254.128', '216.58.208.227'),]

g = nx.Graph()
edgeList = parseOutput
g.add_edges_from(edgeList)

pos = nx.spring_layout(g,scale=1) #default to scale=1
nx.draw(g,pos, with_labels=True)
plt.show()

产量

enter image description here