You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

循环追加Pandas Series至DataFrame失败及列表赋值后变为NoneType的问题排查

问题排查与修复方案

嘿,我一眼就瞅出问题所在了——你误用了Python列表的append()方法!

核心问题解释

Python里的列表是可变对象,append()方法是原地修改原列表,它的返回值是None。当你执行portInfo = portInfo.append([target[0],portsDF])时,相当于把None赋值给了portInfo,这就导致后续它变成了NoneType,完全没法继续存储数据。

快速修复

只需要把赋值语句改成直接调用append就行,不用重新赋值:

# 把这行
portInfo = portInfo.append([target[0],portsDF])
# 改成
portInfo.append([target[0], portsDF])

这样原列表就会被直接修改,不会丢失之前的数据。

优化后的完整代码

我还顺便给你优化了nmap结果的解析逻辑,避免因为行内多空格导致的索引越界问题:

import pandas as pd
import subprocess
from tabulate import tabulate

def vulnScan(targets):
    portInfo = []
    print(type(portInfo))
    columnNames = ["Port","Protocol","State","Service"]
    for target in targets:
        rows = []
        print("Executing: nmap -Pn "+target[1])
        result = subprocess.run(['nmap','-Pn',target[1]], universal_newlines = True, stdout = subprocess.PIPE)
        for line in result.stdout.split("\n"):
            # 过滤掉无关行,只保留有效端口信息行
            if "/" in line and "Starting" not in line and "Nmap done" not in line:
                # 先去除首尾空格再分割,避免多空格导致的列表长度异常
                tableInfo = line.strip().split()
                # 加个长度判断,防止索引越界报错
                if len(tableInfo) >= 4:
                    port = tableInfo[0].split("/")[0]
                    protocol = tableInfo[0].split("/")[1]
                    status = tableInfo[1]
                    service = tableInfo[3]
                    print(port,protocol,status,service)
                    newRow = pd.Series(data=[port,protocol,status,service],index=columnNames)
                    rows.append(newRow)
        portsDF = pd.DataFrame(rows, columns = columnNames)
        print(tabulate(portsDF, headers="keys", tablefmt='psql'))
        # 直接追加到列表,无需赋值
        portInfo.append([target[0], portsDF])
        print(type(portInfo))
        print(portInfo)

额外小建议

如果后续你需要通过主机名快速查找对应的端口DataFrame,用字典存储会比列表更方便:

# 初始化字典
portInfo_dict = {}
# 存储时直接用主机名当键
portInfo_dict[target[0]] = portsDF
# 后续查找直接用portInfo_dict["主机名"]就能拿到对应的DF

另外,手动解析nmap的文本输出容易踩坑,推荐用python-nmap库来处理扫描结果,它能直接解析nmap的输出格式,省去手动分割字符串的麻烦,你可以尝试一下~

内容的提问来源于stack exchange,提问作者Ethel Rusebottom

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 10:42:41