当前位置:   article > 正文

python网络设备信息自动化采集\对比_网站信息自动化采集python csdn

网站信息自动化采集python csdn

一、背景
最近在实施变更时需要采集多台设备信息,用于在实施完毕后对设备状态进行检查。由于人工采集比较耗时,在网上找了一下没找到自动采集的脚本,就用python写了个网络设备信息自动化信息采集脚本,在实施变更前后抓取相关设备信息,实施完成后自动对比前后变化情况。

二、使用提示
1、将设备信息填写在dev_ins.csv表格(表格内容见下图),只支持ssh,思科设备需要输入enable的在enpass列输入enable密码,不需要则不写

2、需要采集信息命令在对应设备下方填写

3、第一条命令为将设备修改全部输出不限制输出行数,否则输出信息不完整

4、目前只适配了Cisco_IOS、H3C_SW、H3C_FW,如有其他设备需求可自行增加
在表格增加相关命令,在代码修改如下变量(fac\cmd),cmdread[9] 数字9与表格列数相对应(从0开始数)
在代码中修改如下变量:

    if fac == "H3C_SW":
        for cmdread in islice(cmd_file, 1, None):
            cmd += cmdread[9] + chr(10)
  • 1
  • 2
  • 3

5、csv表格内不要写中文

6、csv表格与脚本需要放在同一个文件夹执行

7、第一次采集与第二次采集时间如果不是同一天,在信息比对时需要修改文件名称为同一天

8、第一次采集与第二次采集信息比对时,是通过csv表格里面的IP地址来确认比对对象

9、测试环境python3.9

构造如下csv表格:
构造一个如图的dev_ins.csv表格,和脚本放在同一个文件夹

完整代码如下:

import csv
import os
import paramiko
import time
import sys
import difflib
import datetime
from itertools import islice
from datetime import datetime, date, timedelta


now = str(date.today())
filename = 'dev_ins.csv'  # 设备信息、执行命令表格名称
path_before = 'C:/check/collect_info/' + now + '/' + 'before'  # 第一次采集信息保存路径
path_after = 'C:/check/collect_info/' + now + '/' + 'after'  # 第二次采集信息保存路径
path_compare = 'C:/check/result_comp/'  # 第一次第二次采集信息比对结果保存路径


def check_path():
    isExists_before = os.path.exists(path_before)
    isExists_after = os.path.exists(path_after)
    isExists = os.path.exists(path_compare)
    if not isExists_before:
        os.makedirs(path_before)
    if not isExists_after:
        os.makedirs(path_after)
    if not isExists:
        os.makedirs(path_compare)


def ssh_login():
    cache = []
    global host
    global fac
    global login
    global user
    global passw
    global enpass
    global ssh
    global channel
    set_interval_time()
    print('开始采集设备信息....')
    cmd_file = csv.reader(open(filename, 'r', encoding='UTF-8'))
    for line in islice(cmd_file, 1, None):
        if line[0] != "":
            cache.append(line[0:6])
    for hostread in cache:
        host = hostread[0]
        fac = hostread[1]
        login = hostread[2]
        user = hostread[3]
        passw = hostread[4]
        enpass = hostread[5]
        ssh = paramiko.SSHClient()
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        try:
            ssh.connect(hostname=host, port=22, username=user, password=passw, timeout=3)
        except BaseException as e:
            print('{0} 登录失败,请确认账户密码\网络连通性!!!'.format(host), e, '\n')
            log = host + '登录失败,请确认账户密码\网络连通性!!!\t' + str(e) + '\t' + str(datetime.now())+'\n'
            with open(path_before + '/' + 'faillog.txt', "a+", encoding='UTF-8') as rfile:
                rfile.write(log)
            continue
        channel = ssh.invoke_shell()
        print(host + '    ' + 'collecting' + '    ' + 'information' + '    ' + 'start')
        collect_info()
        format_txt()
    print('信息采集完成,保存路径:{0}/'.format(file_save_path))
    input('按任意键返回菜单')


def collect_info():
    cmd = ''
    global cmdread
    channel.send(chr(13))
    cmd_file = csv.reader(open(filename, 'r', encoding='UTF-8'))
    if fac == "Cisco_IOS":
        # 如果dev_ins.csv表格中enpass列不为空则输入enable密码
        if enpass:
            channel.send('enable' + chr(13))
            channel.send(enpass + chr(13))
        for cmdread in islice(cmd_file, 1, None):  # 读取表格中的命令到cmd变量
            cmd += cmdread[8] + chr(10)
        ssh_exec(cmd)  # 执行cmd命令
    if fac == "H3C_SW":
        for cmdread in islice(cmd_file, 1, None):
            cmd += cmdread[9] + chr(10)
        ssh_exec(cmd)
    if fac == "H3C_FW":
        for cmdread in islice(cmd_file, 1, None):
            cmd += cmdread[10] + chr(10)
        ssh_exec(cmd)
    ssh.close()
    return


def ssh_exec(cmd):
    global file_save_path
    if flage == 1:
        file_save_path = path_before
    elif flage == 2:
        file_save_path = path_after
    if cmd:
        channel.send(cmd)
        time.sleep(interval_time)  # 执行cmd命令后等待结果输出,时间间隔设置太短会导致输出不完整,
                                   # 程序就结束了,通常配置不是太多的情况下3S内即可
        output = channel.recv(4096000).decode(encoding='gbk')  # 输出结果里面包含中文,编码用的gbk
        if cmdread[8] not in output:  # 检查最后一条命令是否在输出结果里面
            print('采集配置不完整,请调大间隔时间后重试。')
            sys.exit()
    with open(file_save_path + '/' + host + ".txt", "a+", encoding='gbk') as rfile:
        rfile.write(output)
    print(host + '    ' + 'collecting' + '    ' + 'information' + '    ' + 'stop' + '\n')


def set_interval_time():
    global interval_time
    fla = 0
    interval_time = 2
    answer = input('是否修改命令执行间隔时间(默认为{0}s)y/n:'.format(interval_time))
    while True:
        if fla == 1:
            break
        if answer == 'y':
            try:
                interval_time = float(input('请输入间隔时间(s):'))
            except BaseException:
                print('输入有误,请重新输入!')
            else:
                fla = 1
        else:
            fla = 1
    return


def format_txt():  # 输出结果空行太多,将空行去掉
    global comp_path
    if flage == 1:
        comp_path = path_before
    elif flage == 2:
        comp_path = path_after
    with open(comp_path + '/' + host + '.txt', "r", encoding='gbk') as rfile:
        line = rfile.read()
        line = line.replace('\n', '&')
        with open(comp_path + '/' + host + '.txt', "w", encoding='gbk') as dfile:
            line = line.replace('&&&', '\n')
            line = line.replace('&&', '\n')
            line = line.replace('&', '\n')
            dfile.write(line)
    return


def comp_read_file(file_name):
    try:
        file_desc = open(file_name, 'r', encoding='utf-8')
        text = file_desc.read().splitlines()
        file_desc.close()
        return text
    except IOError as error:
        print('文件读取失败,请确认文件是否存在!{0}'.format(error))
        input('按任意键退出。')
    sys.exit()


def comp_file(file1, file2):
    global result_fiel
    if file1 == "" or file2 == "":
        print('文件不存在,请先收集信息!\n第一个文件的路径:{0}, 第二个文件的路径:{1} .'.format(file1, file2))
        sys.exit()
    text1_lines = comp_read_file(file1)
    text2_lines = comp_read_file(file2)
    diff = difflib.HtmlDiff()
    result = diff.make_file(text1_lines, text2_lines, context=True, charset='utf-8')  
    today = str(date.today())
    result_fiel = path_compare + comp_ip + '-' + today + '.html'
    try:
        with open(path_compare + '/' + comp_ip + '-' + today + '.html', 'w', encoding='UTF-8') as result_file:  # 输出检查结果
            result_file.write(result)
    except IOError as error:
        print('写入错误:{0}'.format(error))


def compare():
    cache = []
    global comp_ip
    host_file = csv.reader(open(filename, 'r', encoding='UTF-8'))
    for line in islice(host_file, 1, None):
        if line[0] != "":
            cache.append(line[0])
    print("开始对比设备信息....")
    for comp_ip in cache:
        today = str(date.today())
        path_today = 'C:/check/collect_info/' + today + '/'
        file_before = path_today + 'before' + '/' + comp_ip + '.txt'
        file_after = path_today + 'after' + '/' + comp_ip + '.txt'
        print('正在检查:' + comp_ip)
        print('文件1名称:' + file_before)
        print('文件2名称:' + file_after + '\n')
        comp_file(file_before, file_after)
    print("对比完毕,结果见附件:{0}".format(result_fiel))
    input('按任意键返回菜单')


def menu():
    print('==============网络设备基线配置采集===============')
    print('(请确认需要采集设备信息是否已导入dev_ins.csv表格)')
    print('1、实施前设备配置、状态信息采集')
    print('2、实施后设备配置、状态信息采集')
    print('3、对比实施前后设备配置、状态')
    print('0、退出')
    print('==============================================')


def main():
    check_path()
    global flage
    while True:
        menu()
        try:
            flage = int(input('请选择:'))
        except BaseException:
            continue
        if flage == 1 or flage == 2:
            ssh_login()
        elif flage == 3:
            compare()
        elif flage == 0:
            break
        else:
            continue
    return


if __name__ == "__main__":
    main()


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/156766?site
推荐阅读
相关标签
  

闽ICP备14008679号