Python 3:如何从嵌套列表生成 table 作为输入
Python 3: How to generate a table from a nested list as input
所以,我得到了以下嵌套列表(我从 Nmap XML 输出文件中解析出来的)。它基本上是 IP 地址及其所有开放端口的列表:
[['192.168.23.78', ['53', '88', '135', '139', '389', '445', '3389']],
['192.168.27.243', ['135', '139', '445', '3389', '5800', '5900']],
['192.168.99.164', ['135', '139', '445', '3389', '5800', '5900']],
['192.168.228.211', ['80']],
['192.168.171.74', ['135', '139', '445', '3389', '5800', '5900']]]
我想根据此数据创建一个 table,其中每个第一项(所有 IP 地址)都打印为行。然后我希望遍历每个第二项(每个 IP 地址的所有端口的列表),并计算每个唯一的端口号。我希望这个新计算的唯一端口列表打印为我的 table 的列 headers。我的空 table 应该大致如下所示:
53 80 88 135 139 389 445 3389 5800 5900
192.168.23.78
192.168.27.243
192.168.99.164
192.168.228.211
192.168.171.74
然后我希望在具有给定开放端口的每个 IP 地址的每个正确单元格中放置 X,如下所示:
53 80 88 135 139 389 445 3389 5800 5900
192.168.23.78 X X X X X X
192.168.27.243 X X X X X X
192.168.99.164 X X X X X X
192.168.228.211 X
192.168.171.74 X X X X X X
我将如何处理我的数据集?
我完全是个新手,但我可能会想出如何遍历所有端口号并获得唯一的端口列表。但我完全不知道如何在正确的单元格
中绘制 table 上的 X
到目前为止,这是我的代码:
#!/usr/bin/env python
from pprint import pprint
import xml.etree.ElementTree as ET
def loopy(item):
for port in host.findall('ports/port'):
if port.get('protocol') == "tcp":
portid = port.get('portid')
for state in port.findall('state'):
if state.get('state') == "open":
if item == "address":
list_addr.append(addr)
return
elif item == "portid":
list_portid.append(portid)
root = ET.parse('scan5.xml').getroot()
result = []
for host in root.findall('host'):
list_portid = []
list_addr = []
address = host.find('address')
addr = address.get('addr')
loopy("address")
loopy("portid")
if list_addr:
result.append([list_addr[0], list_portid])
pprint(result)
我的嵌套列表现在在 result
中,但我不知道如何从中创建 table。
到目前为止我的代码只生成原始列表:
[['10.133.23.78', ['53', '88', '135', '139', '389', '445', '3389']],
['10.133.27.243', ['135', '139', '445', '3389', '5800', '5900']],
['10.133.99.164', ['135', '139', '445', '3389', '5800', '5900']],
['10.135.228.211', ['80']],
['10.133.171.74', ['135', '139', '445', '3389', '5800', '5900']]]
你可以使用安装和使用 prettytable 包来可视化 pretty table
第一pip install prettytable
然后代码
from prettytable import PrettyTable
data = [['192.168.23.78', ['53', '88', '135', '139', '389', '445', '3389']],
['192.168.27.243', ['135', '139', '445', '3389', '5800', '5900']],
['192.168.99.164', ['135', '139', '445', '3389', '5800', '5900']],
['192.168.228.211', ['80']],
['192.168.171.74', ['135', '139', '445', '3389', '5800', '5900']]]
ports = sorted(set([int(port) for _, open_ports in data for port in open_ports]))
my_table = PrettyTable()
header = ['ip']
header.extend(ports)
my_table.field_names = header
for ip_address, open_ports in data:
row = [ip_address]
row.extend('X' if str(port) in open_ports else '' for port in ports)
my_table.add_row(row)
print(my_table)
输出
+-----------------+----+----+----+-----+-----+-----+-----+------+------+------+
| ip | 53 | 80 | 88 | 135 | 139 | 389 | 445 | 3389 | 5800 | 5900 |
+-----------------+----+----+----+-----+-----+-----+-----+------+------+------+
| 192.168.23.78 | X | | X | X | X | X | X | X | | |
| 192.168.27.243 | | | | X | X | | X | X | X | X |
| 192.168.99.164 | | | | X | X | | X | X | X | X |
| 192.168.228.211 | | X | | | | | | | | |
| 192.168.171.74 | | | | X | X | | X | X | X | X |
+-----------------+----+----+----+-----+-----+-----+-----+------+------+------+
使用 numpy
和 pandas
你可以做到
import pandas as pd
import numpy as np
table = [['192.168.23.78', ['53', '88', '135', '139', '389', '445', '3389']],
['192.168.27.243', ['135', '139', '445', '3389', '5800', '5900']],
['192.168.99.164', ['135', '139', '445', '3389', '5800', '5900']],
['192.168.228.211', ['80']],
['192.168.171.74', ['135', '139', '445', '3389', '5800', '5900']]]
# Collect the ip_addresses
ip_addresses = [el[0] for el in table]
# Collect the column names. Temporarily convert to integers to sort them properly
columns = sorted(np.unique([c for el in table for c in el[1]]), key = lambda x: int(x))
# Initialize numpy matrix to hold strings
table_matrix = np.zeros((len(ip_addresses), len(columns)), str)
for row in table:
# Get the row index of the IP address
for i, ip in enumerate(ip_addresses):
if row[0] == ip:
rdx = i
# Check which columns have values in the row that corresponds to the IP address
for c in row[1]:
for j, col in enumerate(columns):
# Add an X if the row has that column
if c == col:
table_matrix[rdx, j] = 'X'
# Create DataFrame
df = pd.DataFrame(table_matrix, index = ip_addresses, columns = columns)
输出:
Out[24]:
53 80 88 135 139 389 445 3389 5800 5900
192.168.23.78 X X X X X X X
192.168.27.243 X X X X X X
192.168.99.164 X X X X X X
192.168.228.211 X
192.168.171.74 X X X X X X
所以,我得到了以下嵌套列表(我从 Nmap XML 输出文件中解析出来的)。它基本上是 IP 地址及其所有开放端口的列表:
[['192.168.23.78', ['53', '88', '135', '139', '389', '445', '3389']],
['192.168.27.243', ['135', '139', '445', '3389', '5800', '5900']],
['192.168.99.164', ['135', '139', '445', '3389', '5800', '5900']],
['192.168.228.211', ['80']],
['192.168.171.74', ['135', '139', '445', '3389', '5800', '5900']]]
我想根据此数据创建一个 table,其中每个第一项(所有 IP 地址)都打印为行。然后我希望遍历每个第二项(每个 IP 地址的所有端口的列表),并计算每个唯一的端口号。我希望这个新计算的唯一端口列表打印为我的 table 的列 headers。我的空 table 应该大致如下所示:
53 80 88 135 139 389 445 3389 5800 5900
192.168.23.78
192.168.27.243
192.168.99.164
192.168.228.211
192.168.171.74
然后我希望在具有给定开放端口的每个 IP 地址的每个正确单元格中放置 X,如下所示:
53 80 88 135 139 389 445 3389 5800 5900
192.168.23.78 X X X X X X
192.168.27.243 X X X X X X
192.168.99.164 X X X X X X
192.168.228.211 X
192.168.171.74 X X X X X X
我将如何处理我的数据集?
我完全是个新手,但我可能会想出如何遍历所有端口号并获得唯一的端口列表。但我完全不知道如何在正确的单元格
中绘制 table 上的 X到目前为止,这是我的代码:
#!/usr/bin/env python
from pprint import pprint
import xml.etree.ElementTree as ET
def loopy(item):
for port in host.findall('ports/port'):
if port.get('protocol') == "tcp":
portid = port.get('portid')
for state in port.findall('state'):
if state.get('state') == "open":
if item == "address":
list_addr.append(addr)
return
elif item == "portid":
list_portid.append(portid)
root = ET.parse('scan5.xml').getroot()
result = []
for host in root.findall('host'):
list_portid = []
list_addr = []
address = host.find('address')
addr = address.get('addr')
loopy("address")
loopy("portid")
if list_addr:
result.append([list_addr[0], list_portid])
pprint(result)
我的嵌套列表现在在 result
中,但我不知道如何从中创建 table。
到目前为止我的代码只生成原始列表:
[['10.133.23.78', ['53', '88', '135', '139', '389', '445', '3389']],
['10.133.27.243', ['135', '139', '445', '3389', '5800', '5900']],
['10.133.99.164', ['135', '139', '445', '3389', '5800', '5900']],
['10.135.228.211', ['80']],
['10.133.171.74', ['135', '139', '445', '3389', '5800', '5900']]]
你可以使用安装和使用 prettytable 包来可视化 pretty table
第一pip install prettytable
然后代码
from prettytable import PrettyTable
data = [['192.168.23.78', ['53', '88', '135', '139', '389', '445', '3389']],
['192.168.27.243', ['135', '139', '445', '3389', '5800', '5900']],
['192.168.99.164', ['135', '139', '445', '3389', '5800', '5900']],
['192.168.228.211', ['80']],
['192.168.171.74', ['135', '139', '445', '3389', '5800', '5900']]]
ports = sorted(set([int(port) for _, open_ports in data for port in open_ports]))
my_table = PrettyTable()
header = ['ip']
header.extend(ports)
my_table.field_names = header
for ip_address, open_ports in data:
row = [ip_address]
row.extend('X' if str(port) in open_ports else '' for port in ports)
my_table.add_row(row)
print(my_table)
输出
+-----------------+----+----+----+-----+-----+-----+-----+------+------+------+
| ip | 53 | 80 | 88 | 135 | 139 | 389 | 445 | 3389 | 5800 | 5900 |
+-----------------+----+----+----+-----+-----+-----+-----+------+------+------+
| 192.168.23.78 | X | | X | X | X | X | X | X | | |
| 192.168.27.243 | | | | X | X | | X | X | X | X |
| 192.168.99.164 | | | | X | X | | X | X | X | X |
| 192.168.228.211 | | X | | | | | | | | |
| 192.168.171.74 | | | | X | X | | X | X | X | X |
+-----------------+----+----+----+-----+-----+-----+-----+------+------+------+
使用 numpy
和 pandas
你可以做到
import pandas as pd
import numpy as np
table = [['192.168.23.78', ['53', '88', '135', '139', '389', '445', '3389']],
['192.168.27.243', ['135', '139', '445', '3389', '5800', '5900']],
['192.168.99.164', ['135', '139', '445', '3389', '5800', '5900']],
['192.168.228.211', ['80']],
['192.168.171.74', ['135', '139', '445', '3389', '5800', '5900']]]
# Collect the ip_addresses
ip_addresses = [el[0] for el in table]
# Collect the column names. Temporarily convert to integers to sort them properly
columns = sorted(np.unique([c for el in table for c in el[1]]), key = lambda x: int(x))
# Initialize numpy matrix to hold strings
table_matrix = np.zeros((len(ip_addresses), len(columns)), str)
for row in table:
# Get the row index of the IP address
for i, ip in enumerate(ip_addresses):
if row[0] == ip:
rdx = i
# Check which columns have values in the row that corresponds to the IP address
for c in row[1]:
for j, col in enumerate(columns):
# Add an X if the row has that column
if c == col:
table_matrix[rdx, j] = 'X'
# Create DataFrame
df = pd.DataFrame(table_matrix, index = ip_addresses, columns = columns)
输出:
Out[24]:
53 80 88 135 139 389 445 3389 5800 5900
192.168.23.78 X X X X X X X
192.168.27.243 X X X X X X
192.168.99.164 X X X X X X
192.168.228.211 X
192.168.171.74 X X X X X X