在网络运维场景中,批量采集多台华为路由器的接口状态并整理为结构化数据,是提升运维效率、快速定位网络问题的核心操作。本文将详细讲解如何基于 Python 的 Paramiko 库,实现 SSH 批量登录华为路由器、采集接口状态,并将结果导出为 CSV 文件,完成网络状态的高效汇总与分析。
一、功能概述
本脚本核心能力如下:
批量 SSH 连接指定列表中的华为路由器;
自动关闭终端分页限制,确保接口状态信息完整采集;
执行display interface brief命令获取接口状态数据;
汇总多台设备数据并导出为 CSV 文件,便于后续分析。
二、环境准备
首先安装脚本依赖的 Paramiko 库(Python SSH 协议实现库):
bash
运行
pip install paramiko
三、完整代码实现
python
运行
import paramiko
import time
import csv
from typing import Dict, Optional

路由器信息配置列表

routers = [
{‘ip’: ‘20.1.1.2’, ‘username’: ‘huawei’, ‘password’: ‘yourpassword’},
{‘ip’: ‘20.1.1.3’, ‘username’: ‘huawei’, ‘password’: ‘yourpassword’},
{‘ip’: ‘20.1.1.4’, ‘username’: ‘huawei’, ‘password’: ‘yourpassword’},
{‘ip’: ‘20.1.1.6’, ‘username’: ‘huawei’, ‘password’: ‘yourpassword’},
{‘ip’: ‘20.1.1.7’, ‘username’: ‘huawei’, ‘password’: ‘yourpassword’},
{‘ip’: ‘20.1.1.8’, ‘username’: ‘huawei’, ‘password’: ‘yourpassword’},
{‘ip’: ‘20.1.1.10’, ‘username’: ‘huawei’, ‘password’: ‘yourpassword’},
{‘ip’: ‘20.1.1.11’, ‘username’: ‘huawei’, ‘password’: ‘yourpassword’},
{‘ip’: ‘20.1.1.12’, ‘username’: ‘huawei’, ‘password’: ‘yourpassword’},
{‘ip’: ‘20.1.1.13’, ‘username’: ‘huawei’, ‘password’: ‘yourpassword’},
{‘ip’: ‘20.1.1.14’, ‘username’: ‘huawei’, ‘password’: ‘yourpassword’},
{‘ip’: ‘20.1.1.15’, ‘username’: ‘huawei’, ‘password’: ‘yourpassword’},
{‘ip’: ‘20.1.1.16’, ‘username’: ‘huawei’, ‘password’: ‘yourpassword’},
{‘ip’: ‘20.1.1.17’, ‘username’: ‘huawei’, ‘password’: ‘yourpassword’},
{‘ip’: ‘20.1.1.18’, ‘username’: ‘huawei’, ‘password’: ‘yourpassword’},
{‘ip’: ‘20.1.1.19’, ‘username’: ‘huawei’, ‘password’: ‘yourpassword’},
{‘ip’: ‘20.1.1.21’, ‘username’: ‘huawei’, ‘password’: ‘yourpassword’},
{‘ip’: ‘20.1.1.22’, ‘username’: ‘huawei’, ‘password’: ‘yourpassword’},
{‘ip’: ‘20.1.1.26’, ‘username’: ‘huawei’, ‘password’: ‘yourpassword’},
{‘ip’: ‘20.1.1.27’, ‘username’: ‘huawei’, ‘password’: ‘yourpassword’},
{‘ip’: ‘20.1.1.31’, ‘username’: ‘huawei’, ‘password’: ‘yourpassword’},
{‘ip’: ‘20.1.1.32’, ‘username’: ‘huawei’, ‘password’: ‘yourpassword’},
{‘ip’: ‘20.1.1.33’, ‘username’: ‘huawei’, ‘password’: ‘yourpassword’},
{‘ip’: ‘20.1.1.36’, ‘username’: ‘huawei’, ‘password’: ‘yourpassword’},
{‘ip’: ‘20.1.1.37’, ‘username’: ‘huawei’, ‘password’: ‘yourpassword’},
{‘ip’: ‘20.1.1.38’, ‘username’: ‘huawei’, ‘password’: ‘yourpassword’},
{‘ip’: ‘20.1.1.39’, ‘username’: ‘huawei’, ‘password’: ‘yourpassword’},
{‘ip’: ‘20.1.1.41’, ‘username’: ‘huawei’, ‘password’: ‘yourpassword’},
{‘ip’: ‘20.1.1.42’, ‘username’: ‘huawei’, ‘password’: ‘yourpassword’},
{‘ip’: ‘20.1.1.43’, ‘username’: ‘huawei’, ‘password’: ‘yourpassword’},
{‘ip’: ‘20.1.1.44’, ‘username’: ‘huawei’, ‘password’: ‘yourpassword’},
{‘ip’: ‘20.1.1.46’, ‘username’: ‘huawei’, ‘password’: ‘yourpassword’},
{‘ip’: ‘20.1.1.47’, ‘username’: ‘huawei’, ‘password’: ‘yourpassword’},
{‘ip’: ‘20.1.1.48’, ‘username’: ‘huawei’, ‘password’: ‘yourpassword’},
{‘ip’: ‘20.1.1.49’, ‘username’: ‘huawei’, ‘password’: ‘yourpassword’},
{‘ip’: ‘20.1.1.52’, ‘username’: ‘huawei’, ‘password’: ‘yourpassword’},
{‘ip’: ‘20.1.1.53’, ‘username’: ‘huawei’, ‘password’: ‘yourpassword’},
{‘ip’: ‘20.1.1.54’, ‘username’: ‘huawei’, ‘password’: ‘yourpassword’},
{‘ip’: ‘20.1.1.55’, ‘username’: ‘huawei’, ‘password’: ‘yourpassword’},
{‘ip’: ‘20.1.1.56’, ‘username’: ‘huawei’, ‘password’: ‘yourpassword’},
{‘ip’: ‘20.1.1.57’, ‘username’: ‘huawei’, ‘password’: ‘yourpassword00’},
{‘ip’: ‘20.1.1.58’, ‘username’: ‘huawei’, ‘password’: ‘yourpassword’},
{‘ip’: ‘20.1.1.59’, ‘username’: ‘huawei’, ‘password’: ‘yourpassword’},
{‘ip’: ‘20.1.1.60’, ‘username’: ‘huawei’, ‘password’: ‘yourpassword’},
{‘ip’: ‘20.1.1.61’, ‘username’: ‘huawei’, ‘password’: ‘yourpassword’},
{‘ip’: ‘20.1.1.62’, ‘username’: ‘huawei’, ‘password’: ‘yourpassword’},
{‘ip’: ‘20.1.1.63’, ‘username’: ‘huawei’, ‘password’: ‘yourpassword’},
{‘ip’: ‘20.1.1.64’, ‘username’: ‘huawei’, ‘password’: ‘yourpassword’},
{‘ip’: ‘20.1.1.66’, ‘username’: ‘huawei’, ‘password’: ‘yourpassword’},
{‘ip’: ‘20.1.1.78’, ‘username’: ‘huawei’, ‘password’: ‘yourpassword00’},
{‘ip’: ‘20.1.1.79’, ‘username’: ‘huawei’, ‘password’: ‘yourpassword’},
{‘ip’: ‘20.1.1.80’, ‘username’: ‘huawei’, ‘password’: ‘yourpassword00’},
{‘ip’: ‘20.1.1.81’, ‘username’: ‘huawei’, ‘password’: ‘yourpassword00’},
# 可继续添加更多路由器配置
]

def get_interface_status(ip: str, username: str, password: str) -> Optional[str]:
“””
连接华为路由器,获取接口状态信息

Args:
    ip: 路由器IP地址
    username: 登录用户名
    password: 登录密码

Returns:
    接口状态字符串,连接失败返回None
"""
client = paramiko.SSHClient()
# 自动添加未知主机密钥
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())

try:
    print(f"正在连接路由器 {ip}...")
    # 建立SSH连接(添加超时限制,避免长时间阻塞)
    client.connect(
        hostname=ip,
        port=22,
        username=username,
        password=password,
        timeout=15
    )
    # 调用交互式shell
    shell = client.invoke_shell()
    shell.settimeout(10)
    
    # 关闭终端分页,确保输出完整
    shell.send('screen-length 0 temporary\n')
    time.sleep(3)  # 等待命令执行
    shell.recv(65535).decode('utf-8', errors='ignore')  # 清空缓冲区
    
    # 发送获取接口状态命令
    shell.send('display interface brief\n')
    time.sleep(8)  # 根据设备响应速度调整等待时间
    # 读取命令输出(忽略编码错误,避免中文乱码)
    output = shell.recv(65535).decode('utf-8', errors='ignore')
    return output
    
except Exception as e:
    print(f"连接路由器 {ip} 出错: {str(e)}")
    return None
    
finally:
    # 确保SSH连接正常关闭
    if client.get_transport() and client.get_transport().is_active():
        client.close()

def save_to_csv(data: Dict[str, str], filename: str = ‘router_interface_status.csv’) -> None:
“””
将路由器接口状态保存到CSV文件(UTF-8编码避免中文乱码)

Args:
    data: 字典格式,key为路由器IP,value为接口状态
    filename: 输出CSV文件名
"""
with open(filename, mode='w', newline='', encoding='utf-8') as file:
    writer = csv.writer(file)
    # 写入表头
    writer.writerow(['路由器IP', '接口状态信息'])
    
    # 批量写入数据
    for ip, status in data.items():
        writer.writerow([ip, status])

if name == “main“:
# 存储采集结果
interface_results = {}

# 遍历所有路由器,批量采集
for router in routers:
    ip = router['ip']
    username = router['username']
    password = router['password']
    status_info = get_interface_status(ip, username, password)
    if status_info:
        interface_results[ip] = status_info
        print(f"✅ 已获取 {ip} 接口状态")
    else:
        print(f"❌ 未获取到 {ip} 接口状态")

# 导出到CSV(判断有效数据,避免生成空文件)
if interface_results:
    save_to_csv(interface_results)
    print(f"\n������ 采集完成!结果已保存到 {filename if 'filename' in locals() else 'router_interface_status.csv'}")
else:
    print("\n⚠️  未采集到任何路由器接口状态数据")