通过 networkx 并使用 python 在图中添加节点和边
Add nodes & edges in graph via networkx and using python
我需要创建一个 IP 地址图并标记它们之间的边,为此我编写了下面的代码。列表,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')
...
当我 运行 此代码时,出现以下错误:
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
import logging, sys, struct, binascii, socket
from scapy.all import *
import networkx as nx
import matplotlib.pyplot as plt
pkts=rdpcap("pcapFile.pcap",20)
def parsePcap():
IPList = [[] for i in range (20)]
count = 0
for pkt in pkts:
#print pkt.summary()
if pkt.haslayer(IP):
#proto = pkt.getLayer(IP).proto
x = pkt.getlayer(IP).src
y = pkt.getlayer(IP).dst
IPList[count]= (x,y)
#IPList[count].append(proto)
print IPList[count]
count += 1
return IPList
parseOutput = parsePcap()
nodeList = parseOutput
edgeList = parseOutput
g = nx.Graph()
g.add_nodes_from(nodeList)
print g.number_of_nodes
g.add_edges_from(edgeList)
pos = nx.spring_layout(g,scale=1) #default to scale=1
nx.draw(g,pos)
我什至不知道我做错了什么。该文档并没有说明太多
所有在线示例似乎都是用与我的代码相同的语法编写的。
您看到的问题是由
引起的
IPList = [[] for i in range (20)]
当 len(pkts)
小于 20 时,这会导致 parsePcap()
返回带有空列表或末尾列表的序列列表:
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
.
相同
如果您要声明 nodeList
,
nodeList
应该是 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()
产量
我需要创建一个 IP 地址图并标记它们之间的边,为此我编写了下面的代码。列表,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')
...
当我 运行 此代码时,出现以下错误:
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
import logging, sys, struct, binascii, socket
from scapy.all import *
import networkx as nx
import matplotlib.pyplot as plt
pkts=rdpcap("pcapFile.pcap",20)
def parsePcap():
IPList = [[] for i in range (20)]
count = 0
for pkt in pkts:
#print pkt.summary()
if pkt.haslayer(IP):
#proto = pkt.getLayer(IP).proto
x = pkt.getlayer(IP).src
y = pkt.getlayer(IP).dst
IPList[count]= (x,y)
#IPList[count].append(proto)
print IPList[count]
count += 1
return IPList
parseOutput = parsePcap()
nodeList = parseOutput
edgeList = parseOutput
g = nx.Graph()
g.add_nodes_from(nodeList)
print g.number_of_nodes
g.add_edges_from(edgeList)
pos = nx.spring_layout(g,scale=1) #default to scale=1
nx.draw(g,pos)
我什至不知道我做错了什么。该文档并没有说明太多 所有在线示例似乎都是用与我的代码相同的语法编写的。
您看到的问题是由
引起的IPList = [[] for i in range (20)]
当 len(pkts)
小于 20 时,这会导致 parsePcap()
返回带有空列表或末尾列表的序列列表:
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
.
如果您要声明 nodeList
,
nodeList
应该是 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()
产量