Python爬取HAProxy数据

1.简单了解负载均衡(高并发):https://blog.csdn.net/github_37515779/article/details/79953788

2.简单了解HAProxy:https://blog.csdn.net/kelgon/article/details/56013830

3.爬取HAProxy基本信息代码:(用的是beautifulsoup和正则表达式,最终将数据放入csv文件中)

其中涉及到了http的 Authorization: Basic 认证登录问题!

网页样式截图:

代码如下:

import csv
import psycopg2
import urllib.request
import types
import re
import bs4
from bs4 import BeautifulSoup
#python3 中用urllib.request库代替了urllib2

#登录的用户名和密码
username = "admin"
password = "-----"
url="http://-----.30:8008/stats"

#模拟http Authorization: Basic 认证登录的函数
def Func(url, username, password):
    try:
        # 创建一个密码管理者
        password_mgr = urllib.request.HTTPPasswordMgrWithDefaultRealm()
        # 添加用户名和密码
        password_mgr.add_password(None, url, username, password)
        # 创建了一个新的handler
        handler = urllib.request.HTTPBasicAuthHandler(password_mgr)
        # 创建 "opener"
        opener = urllib.request.build_opener(handler)
        # 使用 opener 获取一个URL
        opener.open(url)
        # 安装 opener.
        urllib.request.install_opener(opener)
        #urllib2.urlopen 使用上面的opener.
        ret = urllib.request.urlopen(url)
        return ret.read()
    except urllib.request.HTTPError as e:
        if e.code == 401:
           return "authorization failed"
        else:
           return e
    except:
        return None


#获取服务器名称
def server_name(soup):
    #表名称可定位到<a class = "px".....></a>
    title1 = soup.find_all("a",class_ = "px")
    #print(title1)
    #用正则表达式输出表名称数据
    table_title = re.findall(">(.*?)</a>",str(title1))
    return table_title


#找出表头信息,因为每个服务器属性相同,所以含有相同的表头
def serve_tabel_titles(text):
    #表头第一列信息
    table_row1 = text[1].find_all("tr",class_ = "titre")
    row1 = re.findall("colspan=\"[0-9]\">(.{5,12})</th>",str(table_row1))
    #表头第一列每个属性占空间大小
    space = re.findall("colspan=\"(.*?)\">",str(table_row1))

    i=0   #i初始化,当作临时变量
    #将第一列按照空隙补全, 且付给table_row
    table_row = row1[:]  # 用切片赋值,改变table_row的值不会改变table_row_1的值,如果直接为a=b,则有关联
    for j in row1:
        for k in range(0,int(space[i])-1):
            k+=1
            table_row.insert(table_row.index(j), j)
        i+=1
    #表第二列信息
    row2 = re.findall("<th>(.{2,7})</th>",str(table_row1))
    #将第二列信息与第一列相对应,放在一个二维数组中(table_header),统称为表的头信息
    table_header = list(zip(table_row,row2))
    return table_header


#找出每个服务器需要的检测方式(即每个表的数据有几行)
def serve_data_line(tables,number):
    table_rows = tables[number].find_all("td",class_ = "ac")
    table_a = re.findall(">(.{2,10})</a>",str(table_rows))
    return table_a


#将数据按照规则爬取得到,然后再存放于csv文件中
def find_save_datas(reserve_table_tr,names,titles,lines,file_name):
    line_number = 0  # 给line计数,进行标记
    writer = csv.writer(file_name)
    for datas in reserve_table_tr:
        result = []
        space = ['0']
        if len(str(datas))<10:
            continue
        for data in datas:
            table_row_data = re.findall(">(.{1,25}?)</td>",str(data))
            space_data = re.findall("colspan=\"(.*?)\">",str(data))
            #因为有的空格占位超过1个,所以遇到这种情况,需要找出,用空格将数据补全
            if not len(table_row_data):
                table_row_data = ['0']
            if len(space_data):
                for add_space in range(int(space_data[0])-1):
                    result.append(space)
            result.append(table_row_data)
        #将第一个元素(多余元素),删除
        result.pop(0)
        #result是一行采集到的数据,下面需要将信息存放在csv文档中
        # 建立一个csv文件,数据存放格式为 表名称->一级列名->二级列名->行名->数据(www->balancer->Queue->Cur->Frontend)
        line_datas = []
        for i in range(len(result)):
            line_data = []
            line_data.append(names)
            line_data.append(titles[i][0])
            line_data.append(titles[i][1])
            line_data.append(lines[line_number])
            line_data.append(result[i][0])
            #print(line_data)
            writer.writerow(line_data)
            line_datas.append(line_data)
        print(line_datas)
        line_number += 1


#通过beautifulsoup爬取网页,并用html.parser进行解析
soup = BeautifulSoup(Func(url,username,password),'html.parser')
#print(soup)
tables = soup.find_all("table",class_ = "tbl")
all_server_names = server_name(soup)       #检测设备的名称(服务器名称)
titles = serve_tabel_titles(tables)  #表表头标签,是一个二维列表,存放的是一级和二级表头

#打开文件进行数据读写,因为要将多个表信息都存放在同一个文件中
file_name = open("stats_data_table.csv", "w", newline="",encoding="utf-8")

server_number = 0
for i in range(len(tables)):
    if i%2 ==1:
        names = all_server_names[server_number]
        server_number += 1
        lines = serve_data_line(tables, i)  # 表每行的名称,即检测方式
        # 将采集得到的数据进行优化,过滤掉有碍于爬取数据的标签
        # 去除标签可以使用正则re.sub()
        table_tr = tables[i].find_all("tr", attrs={"class": {"frontend", "active_up", "backend"}})
        reserve_table_tr = re.sub("<span.*?>|</span>|<u>|</u>|<div.*?/div>", "", str(table_tr))
        reserve_table_tr = bs4.BeautifulSoup(reserve_table_tr.encode("utf=8"), "html.parser")
        find_save_datas(reserve_table_tr, names, titles, lines, file_name)
    else:
        continue



爬取数据部分截图:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章