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



爬取數據部分截圖:

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