python爬取网页,统计,写到excle表格中

背景:作为运维,因经常需要对最近的报警进行分析,需要将某段时间的报警按照某个指标有序罗列,统计。简单的事情需要搞得很麻烦。所以敲了这几行代码。(运维简单使用python,python大神请多多指点)

# -*- coding: utf-8 -*    

import requests
from collections import OrderedDict
import xlsxwriter
import datetime
import os


def crawling():
    # 1、爬取内容到he列表中
    global he, xu_date, page, response
    xu_date = input("统计哪天的报警汇集信息(例:2020-02-02):")
    # 需要打印哪几页
    qy = int(input("起始页:"))
    zy = int(input("中止页:"))
    he = []
    for i in range(qy, zy+1):
        # 1、爬取网页
        try:
            # 1、获取网页信息
            prefix_url = 'http://***..com/api/v2monitor/alarmlist/?format=json&page='
            di_ye = str(i)
            response = requests.get(prefix_url + di_ye)
            response.raise_for_status()
            response.encoding = response.apparent_encoding
            # 此时response.text为str格式
            key_null = response.text.replace('null', '"none"')
            # 转换为字典用eval
            all_info = eval(key_null)
            # 本页所有报警字典组成的列表。即字典对应的"results":[***]
            # respon.json()把json文件转换为python认识的格式
            # all_info = response.json()

            all_list = all_info["results"]
            # he即为最终想要的列表,未跑去时间状态跟时间
            he += all_list
        except:
            print("爬取失败")

    return he


def unique():
    # 2、清洗数据
    # 定义变量,全局变量和局部变量
    global problem_unique, OK_unique,problem_p_unique
    date_he = []
    problem_list = []
    ok_list = []
    # 如果截取时间==需统计时间,则为所需日期当天的所有报警
    for x in he:
        date = x['create_at'].split(' ')[0]
        if date == xu_date:
            date_he.append(x)

    # 页面中problem与OK信息分离
    for i in date_he:
        if i["status"] != 'OK':
            problem_list.append(i)
        else:
            ok_list.append(i)
    # 将problem列表所有的信息反向排列,即从0:00开始;OK列表时间不动,是倒数。
    problem_list.reverse()

    #  problem信息去重(相同主题的去重)+ 统计定义主题出现次数time
    # 帮助https://blog.csdn.net/chong_yun/article/details/80775909?depth_1-utm_source=distribute.pc_relevant_right.none-task&utm_source=distribute.pc_relevant_right.none-task
    a = OrderedDict() 
    for item in problem_list:
        a.setdefault(item['subject'],{**item, 'time': 0})['time'] += 1
    problem_unique = list(a.values())

    # 把problem_list与problem_unique中主题相同的实例+= 到problem_unique实例中
    for i in problem_list:
        for u in problem_unique:
            if i['subject'] == u['subject']:
                if i['instance'] not in u['instance']:
                    u['instance'] = '%s,%s' % (u['instance'], i['instance'])

    #   OK信息去重(相同主题的去重)
    b = OrderedDict()
    for item in ok_list:
        b.setdefault(item['subject'], {**item, 'time': 0})['time'] += 1
    ok_unique = list(b.values())

    # 计算恢复时间,将恢复时间写入problem_unique列表中
    for a in problem_unique:
        for b in ok_unique:
            if a['subject'].replace('[Alerting] ', '') == b['subject'].replace('[OK] ', ''):
                a['hfsj'] = b['create_at']
            # 若没有恢复时间则设置为''空
            # else:
            #     a['hfsj'] = ''

    # 计算出间隔时间,并写入problem_unique列表中.
    for i in problem_unique:
        if 'hfsj' in i:

            # 将时间格式的str转换为时间格式,先在顶部导入了datetime模块
            baojingshijian = datetime.datetime.strptime(i['create_at'], '%Y-%m-%d %H:%M:%S')
            huifushijian = datetime.datetime.strptime(i['hfsj'], '%Y-%m-%d %H:%M:%S')

            # 计算恢复时间-创建时间的间隔时间
            jiangemiao = (huifushijian - baojingshijian).seconds

            # 将计算出的秒转换为h、min     帮助自:https://blog.csdn.net/qq562029186/article/details/81136096
            m, s = divmod(jiangemiao, 60)
            h, m = divmod(m, 60)
            jgsj = '%d:%d:%d' % (h, m, s)
            i['jgsj'] = jgsj
        else:
            i['hfsj'] = ''
            i['jgsj'] = ''

    # 根据报警级别P 统计报警次数,合并报警主题,统计报警时间和恢复时间
    new_list = OrderedDict()
    for item in problem_unique:
        new_list.setdefault(item['levels'], {**item, 'time': 0})['time'] += item['time']
    problem_p_unique = list(new_list.values())

    # 根据级别列出ok_p_unique列表4个list,用来计算problem_p_unique的恢复时间
    ok_p = OrderedDict()
    for item in ok_list:
        ok_p.setdefault(item['levels'], {**item, 'time': 0})['time'] += 1
    ok_p_unique = list(ok_p.values())

    # 把problem_unique与problem_p_unique中P级别相同的主题+= 到problem_p_unique实例中
    for i in problem_unique:
        for x in problem_p_unique:
            if i['levels'] == x['levels'] and i['subject'] not in x['subject']:
                x['subject'] += i['subject']
                x['subject'] = '%s,%s' % (x['subject'], i['subject'])

    # problem_unique列表,级别相同挑选恢复时间最大的,作为problem_p_unique的恢复时间

    for a in problem_p_unique:
        for b in ok_p_unique:
            if a['levels'] == b['levels']:
                a['hfsj'] = b ['create_at']

    # for i in problem_p_unique:
    #     print(i)

    return problem_unique, ok_unique, problem_p_unique


def to_table():
    # 3、开始搞到excle表的sheet1和sheet2表格中
    #while true
    filename = 'python生成日报.xlsx'
    if os.path.exists(filename):
        os.remove(filename)
    workbook = xlsxwriter.Workbook('./%s' % filename)
    worksheet = workbook.add_worksheet()
    worksheet2 = workbook.add_worksheet()

    # 设定格式,等号左边格式名称自定义,字典中格式为指定选项
    # bold:加粗,num_format:数字格式
    bold_format = workbook.add_format({'bold': True,
                                       'font_size': 12,
                                       'valign': 'vcenter',
                                       'align': 'center'
                                       })
    item_style = workbook.add_format({'font_size': 12,
                                     'valign': 'vcenter',
                                     'align': 'center'})
    riqi_style = workbook.add_format({'font_size': 12,
                                      'valign': 'vcenter',
                                      'align': 'center'})
    money_format = workbook.add_format({'num_format': '$#,##0'})
    date_format = workbook.add_format({'num_format': 'mmmm d yyyy'})

    # 将二行二列设置宽度为15(从0开始)
    # worksheet.set_column(0, 1, 14.88)
    # worksheet.set_column(1, 2, 14.88)
    # worksheet.set_column(2, 3, 8.38)
    # worksheet.set_column(3, 4, 25.13)
    # worksheet.set_column(4, 5, 25.13)
    # worksheet.set_column(5, 6, 25.13)
    # worksheet.set_column(6, 7, 23.13)
    # worksheet.set_column(7, 8, 23.13)
    # worksheet.set_column(8, 9, 14.88)
    # worksheet.set_column(9, 10, 8.38)
    #
    # worksheet2.set_column(0, 1, 9)
    # worksheet2.set_column(1, 2, 9)
    # worksheet2.set_column(2, 3, 60)
    # worksheet2.set_column(3, 4, 15)
    # worksheet2.set_column(4, 5, 15)
    # worksheet2.set_column(5, 6, 15)
    # worksheet2.set_column(6, 7, 15)
    # worksheet2.set_column(7, 8, 15)
    # worksheet2.set_column(8, 9, 15)
    # worksheet2.set_column(9, 10, 24)
    # worksheet2.set_column(10, 11, 24)

    # # 用符号标记位置,例如:A列1行
    worksheet.write('A1', '统计日期', bold_format)
    worksheet.write('B1', '报警来源', bold_format)
    worksheet.write('C1', '报警级别', bold_format)
    worksheet.write('D1', '报警实例', bold_format)
    worksheet.write('E1', '报警主题', bold_format)
    worksheet.write('F1', '报警详情', bold_format)
    worksheet.write('G1', '开始时间', bold_format)
    worksheet.write('H1', '恢复时间', bold_format)
    worksheet.write('I1', '报警总时长', bold_format)
    worksheet.write('J1', '报警总次数', bold_format)

    # 定义邮件文件格式
    worksheet2.merge_range('A1:K1', '监控日报')
    worksheet2.write('A1', '监控日报', bold_format)
    worksheet2.write('A2', '报警级别P', bold_format)
    worksheet2.write('B2', '报警次数', bold_format)
    worksheet2.write('C2', '报警分布', bold_format)
    worksheet2.write('D2', '是否影响业务', bold_format)
    worksheet2.write('E2', '影响内容', bold_format)
    worksheet2.write('F2', '事件级别L', bold_format)
    worksheet2.write('G2', '时间开始时间', bold_format)
    worksheet2.write('H2', '事件恢复时间', bold_format)
    worksheet2.write('I2', '事件时长', bold_format)
    worksheet2.write('J2', '报警开始时间', bold_format)
    worksheet2.write('K2', '报警恢复时间', bold_format)
    worksheet2.write('A3', 'P0', bold_format)
    worksheet2.write('A4', 'P1', bold_format)
    worksheet2.write('A5', 'P2', bold_format)
    worksheet2.write('A6', 'P3', bold_format)
    worksheet2.write('A7', 'P4', bold_format)
    worksheet2.write('A8', 'P5', bold_format)
    worksheet2.write('A9', 'P9', bold_format)
    worksheet2.write('A10', 'P10', bold_format)
    worksheet2.write('A11', '报警总次数', bold_format)

    row = 1
    col = 0
    for item in problem_unique:
        # 使用write_string方法,指定数据格式写入数据
        worksheet.write_string(row, col, str(item['create_at'].split(' ')[0]), riqi_style)
        worksheet.write_string(row, col + 1, str(item['origin']), item_style)
        worksheet.write_string(row, col + 2, str('P'+str(item['levels'])), item_style)
        worksheet.write_string(row, col + 3, str(item['instance']), item_style)
        worksheet.write_string(row, col + 4, str(item['subject']), item_style)
        worksheet.write_string(row, col + 5, str(item['content']), item_style)
        worksheet.write_string(row, col + 6, str(item['create_at'].replace('-', '/')), item_style)
        worksheet.write_string(row, col + 7, str(item['hfsj'].replace('-', '/')), item_style)
        worksheet.write_string(row, col + 8, str(item['jgsj']), item_style)
        worksheet.write_string(row, col + 9, str(item['time']), item_style)
        row += 1

    row = 2
    col = 0
    for a in (0, 1, 2, 3, 4, 5, 9, 10):
        for i in problem_p_unique:
            if a == i['levels']:
                worksheet2.write_string(row, col + 1, str(i['time']), item_style)
                worksheet2.write_string(row, col + 2, str(i['subject']), item_style)
                worksheet2.write_string(row, col + 3, '否', item_style)
                worksheet2.write_string(row, col + 4, '否', item_style)
                worksheet2.write_string(row, col + 9, str(i['create_at']), item_style)
                worksheet2.write_string(row, col + 10, str(i['hfsj']), item_style)
            else:
                pass
        row += 1

    workbook.close()


if __name__ == '__main__':
    crawling()
    unique()
    to_table()

输出excle表格结果如下
在这里插入图片描述

总结:因url为公司内网使用,故对他人并无实际价值。仅作为本人学习记录之用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值