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
爬取數據部分截圖: