Python爬蟲第11節-解析庫Beautiful Soup的使用上篇

目錄

前言

一、Beautiful Soup 簡介

1.1 Beautiful Soup概述

1.2 準備工作

1.3 解析器

二、基本使用

三、節點選擇器的使用

3.1 選擇元素

3.2 提取信息

3.2.1 獲取名稱

3.2.2 獲取屬性

3.2.3 獲取內容

3.3 嵌套選擇

3.4 關聯選擇

3.4.1 子節點和子孫節點

3.4.2 父節點和祖先節點

3.4.3 兄弟節點

3.4.4 提取信息


前言

??????? 在之前的內容中,我們深入探討了正則表達式的多種用法。然而,正則表達式并非十全十美,一旦出現編寫錯誤或邏輯漏洞,最終得到的結果往往與我們的預期大相徑庭。

????????網頁作為一種具有特定結構和層級關系的信息載體,許多節點都通過 id 或 class 進行了明確區分。那么,能否利用這些網頁的結構和屬性特點,找到一種更為高效、準確的提取方法呢?

????????在本節中,我們將為大家介紹一個強大的網頁解析工具 ——Beautiful Soup。它能夠依據網頁的結構和屬性等特性,輕松地對網頁進行解析。使用 Beautiful Soup,我們無需再編寫復雜冗長的正則表達式,只需幾條簡潔明了的語句,就能完成網頁中特定元素的提取工作。

????????接下來,讓我們一起深入了解 Beautiful Soup 的強大功能,開啟高效解析網頁的新篇章!

一、Beautiful Soup 簡介

1.1 Beautiful Soup概述

??????? 簡單來說,BeautifulSoup 是 Python 語言中一個專門用于解析 HTML 或 XML 的強大庫。它提供了極為便捷的方式,能夠輕松地從網頁中抽取我們所需的數據。其官方對 BeautifulSoup 的解釋為:

????????BeautifulSoup 提供了一系列簡單易用、充滿 Python 風格的函數,這些函數可以實現導航、搜索、修改分析樹等多種功能。它就像一個功能齊全的工具箱,通過對文檔進行解析,為用戶精準地提供所需抓取的數據。而且,BeautifulSoup 的使用非常簡便,只需少量的代碼,就能構建出一個功能完整的應用程序。

????????此外,BeautifulSoup 還具備自動轉換編碼的功能。它會自動將輸入的文檔轉換為 Unicode 編碼,輸出的文檔則轉換為 utf - 8 編碼。當然,如果文檔本身沒有指定編碼方式,用戶只需簡單說明原始編碼方式即可。

????????如今,BeautifulSoup 已經與 lxml、html5lib 等一樣,成為了出色的 Python 解釋器。它能夠為用戶靈活地提供不同的解析策略,并且在解析速度方面表現強勁。

????????由此可見,借助 Beautiful Soup,我們可以大大簡化繁瑣的網頁數據提取工作,顯著提升解析效率。

1.2 準備工作

????????在開始使用 Beautiful Soup 進行網頁解析之前,請務必確保已經正確安裝了 Beautiful Soup 和 lxml 庫。如果還沒有安裝,請自行安裝。

1.3 解析器

????????Beautiful Soup 在進行網頁解析時,實際上是依賴于解析器來完成工作的。它不僅支持 Python 標準庫中自帶的 HTML 解析器,還兼容一些功能強大的第三方解析器,比如 lxml。下面的表詳細列出了 Beautiful Soup 所支持的各種解析器。

Beautiful Soup支持的解析器

????????通過上述對比可以清晰地看出,lxml 解析器不僅具備解析 HTML 和 XML 的雙重功能,而且在速度方面表現出色,同時還具有很強的容錯能力。因此,我們強烈推薦使用 lxml 解析器。

????????如果選擇使用 lxml 解析器,在初始化 Beautiful Soup 對象時,只需將第二個參數設置為 lxml 即可。示例代碼如下:

from bs4 import BeautifulSoup
soup = BeautifulSoup('<p>Hello</p>', 'lxml')
print(soup.p.string)

????????在后續關于 Beautiful Soup 的用法實例演示中,我們將統一采用 lxml 解析器進行講解。

二、基本使用

????????下面,我們通過一個具體的實例來深入了解 Beautiful Soup 的基本使用方法:

html = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title" name="dromouse"><b>The Dormouse's story</b></p>
<p class="story">Once upon a time there were three little sisters; and their names were
<a href="http://example.com/elsie" class="sister" id="link1"><!-- Elsie --></a>,
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>
<p class="story">...</p>
"""
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.prettify())
print(soup.title.string)

運行結果:

??????? 在這個例子中,我們首先定義了一個名為 html 的變量,它存儲了一段 HTML 字符串。需要注意的是,這段字符串并不是一個完整的 HTML 字符串,其中的 body 和 html 節點都沒有閉合。

????????接下來,我們將 html 字符串作為第一個參數傳遞給 BeautifulSoup 對象,同時將第二個參數設置為解析器類型 “lxml”,這樣就完成了 BeautifulSoup 對象的初始化,并將其賦值給了 soup 變量。

????????初始化完成后,我們就可以調用 soup 對象的各種方法和屬性,來對這段 HTML 代碼進行解析了。

????????首先,我們調用了 prettify () 方法。這個方法的作用是將待解析的字符串以標準縮進格式輸出,使代碼結構更加清晰易讀。需要特別注意的是,在輸出結果中,我們可以看到原本未閉合的 body 和 html 節點都已經自動閉合了。這并不是 prettify () 方法的作用,而是在初始化 BeautifulSoup 對象時,它就已經自動對不規范的 HTML 字符串進行了格式校正。

????????然后,我們調用了 soup.title.string。這里的 soup.title 可以選中 HTML 中的 title 節點,而 string 屬性則用于獲取該節點中的文本內容。通過這兩個簡單的屬性調用,我們就輕松完成了文本的提取工作,充分體現了 Beautiful Soup 的便捷性。

三、節點選擇器的使用

????????在 Beautiful Soup 中,直接調用節點的名稱就可以選擇對應的節點元素,再調用 string 屬性就能夠獲取節點內的文本內容。這種選擇方式的優點是速度非常快,特別適用于單個節點結構層次清晰的情況。

3.1 選擇元素

下面,我們通過一個具體的例子來詳細說明如何選擇元素:

html = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title" name="dromouse"><b>The Dormouse's story</b></p>
<p class="story">Once upon a time there were three little sisters; and their names were
<a href="http://example.com/elsie" class="sister" id="link1"><!-- Elsie --></a>,
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>
<p class="story">...</p>
"""
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.title)
print(type(soup.title))
print(soup.title.string)
print(soup.head)
print(soup.p)

運行結果:

????????在這個例子中,我們仍然使用了之前的 HTML 代碼。首先,我們打印輸出了 title 節點的選擇結果,可以看到輸出的正是 title 節點及其內部的文字內容。

????????接著,我們輸出了 title 節點的類型,結果是 bs4.element.Tag 類型。這是 Beautiful Soup 中一個非常重要的數據結構,經過選擇器選擇后的結果,通常都是這種 Tag 類型。

????????Tag 類型具有一些實用的屬性,比如 string 屬性。當我們調用 string 屬性時,就可以獲取到節點的文本內容,這也正是接下來的輸出結果。
?

????????然后,我們嘗試選擇了 head 節點,輸出結果顯示的是 head 節點及其內部的所有內容。

????????最后,我們選擇了 p 節點。但這里需要注意的是,輸出結果僅僅是第一個 p 節點的內容,后面的幾個 p 節點并沒有被選中。這表明,當存在多個相同節點時,這種直接調用節點名稱的選擇方式只會選擇到第一個匹配的節點,而忽略后面的其他節點。

3.2 提取信息

????????在前面的演示中,我們展示了如何通過調用 string 屬性來獲取節點文本的值。那么,如何獲取節點屬性的值呢?又如何獲取節點的名稱呢?下面,我們將對這些信息的提取方式進行統一梳理。

3.2.1 獲取名稱

????????在 Beautiful Soup 中,可以利用 name 屬性來獲取節點的名稱。我們還是以上面的文本為例,選取 title 節點,然后調用 name 屬性,就可以得到節點的名稱:

print(soup.title.name)

運行結果:

title

3.2.2 獲取屬性

????????每個節點都可能擁有多個屬性,比如常見的 id 和 class 等。在選擇了一個節點元素后,可以通過調用 attrs 方法來獲取該節點的所有屬性:

print(soup.p.attrs)
print(soup.p.attrs['name'])

運行結果:

??????? 從運行結果可以看出,attrs 的返回結果是一個字典形式,它將選擇的節點的所有屬性和屬性值組合成了一個字典。

????????如果我們想要獲取某個特定的屬性值,比如 name 屬性,就相當于從字典中獲取某個鍵值,只需要使用中括號加上屬性名即可。例如,要獲取 name 屬性的值,可以通過 attrs['name'] 來實現。

????????其實,還有一種更簡便的獲取屬性值的方式,我們可以不用寫 attrs,直接在節點元素后面加上中括號,傳入屬性名就可以獲取屬性值了。示例代碼如下:

print(soup.p['name'])
print(soup.p['class'])

運行結果如下:

dromouse
['title']

????????在這里需要注意的是,不同屬性的返回結果類型可能不同。有的返回結果是字符串,比如 name 屬性的值是唯一的,所以返回的是單個字符串;而對于 class 屬性,一個節點元素可能有多個 class,因此返回的是一個由字符串組成的列表。在實際處理過程中,我們需要根據具體情況判斷屬性值的類型。

3.2.3 獲取內容

????????我們可以利用 string 屬性來獲取節點元素所包含的文本內容。例如,要獲取第一個 p 節點的文本內容,可以使用以下代碼:

print(soup.p.string)

運行結果如下:

The Dormouse's story

????????再次強調,這里選擇到的 p 節點是第一個 p 節點,獲取的文本內容也是第一個 p 節點內部的文本。

3.3 嵌套選擇

????????在前面的例子中,我們知道每一個通過選擇器得到的返回結果都是 bs4.element.Tag 類型。這種類型的對象同樣可以繼續調用節點進行下一步的選擇,也就是所謂的嵌套選擇。

????????例如,我們先獲取了 head 節點元素,然后可以繼續調用 head 節點內部的 title 節點元素:

html = """
<html><head><title>The Dormouse's story</title></head>
<body>
"""
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.head.title)
print(type(soup.head.title))
print(soup.head.title.string)

運行結果如下:

????????第一行輸出結果是我們調用 head 之后再次調用 title 而選擇的 title 節點元素。然后,我們打印輸出了它的類型,可以看到它仍然是 bs4.element.Tag 類型。

????????這說明,我們在 Tag 類型的基礎上再次進行選擇得到的結果依然是 Tag 類型。每次返回的結果類型都相同,這就為我們進行嵌套選擇提供了可能。

????????最后,我們輸出了它的 string 屬性,也就是該節點里的文本內容。

3.4 關聯選擇

????????在實際進行節點選擇時,有時候我們無法一步就選到想要的節點元素,而是需要先選中某一個節點元素,然后以它為基準,再去選擇它的子節點、父節點、兄弟節點等。下面,我們就來詳細介紹如何選擇這些關聯的節點元素。

3.4.1 子節點和子孫節點

????????在選取了一個節點元素之后,如果我們想要獲取它的直接子節點,可以調用 contents 屬性。示例代碼如下:

html = """
<html><head><title>The Dormouse's story</title></head><body><p class="story">Once upon a time there were three little sisters; and their names were<a href="http://example.com/elsie" class="sister" id="link1"><span>Elsie</span></a><a href="http://example.com/lacie" class="sister" id="link2">Lacie</a>and<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>and they lived at the bottom of a well.</p><p class="story">...</p>
"""
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.p.contents)

運行結果如下:

?

????????從運行結果可以看出,返回的結果是一個列表形式。p 節點中既包含了文本內容,又包含了其他節點元素,最終這些內容都會以列表的形式統一返回。

????????需要注意的是,列表中的每個元素都是 p 節點的直接子節點。例如,第一個 a 節點里面包含了一層 span 節點,這相當于 p 節點的孫子節點,但在返回結果中,并沒有單獨把 span 節點選出來。也就是說,contents 屬性得到的結果是直接子節點的列表。

????????同樣,我們也可以調用 children 屬性來得到相應的結果:

from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.p.children)
for i, child in enumerate(soup.p.children):print(i, child)

運行結果如下:

?

????????這里我們使用的是同樣的 HTML 文本,調用 children 屬性后,返回的結果是一個生成器類型。接下來,我們通過 for 循環遍歷輸出了相應的內容。

????????如果我們想要得到所有的子孫節點,可以調用 descendants 屬性:

from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.p.descendants)
for i, child in enumerate(soup.p.descendants):print(i, child)

運行結果如下:

????????此時返回的結果依然是一個生成器。通過遍歷輸出可以看到,這次的輸出結果包含了 span 節點。這是因為 descendants 屬性會遞歸查詢所有子節點,從而得到所有的子孫節點。

3.4.2 父節點和祖先節點

????????如果我們要獲取某個節點元素的父節點,可以調用 parent 屬性。示例代碼如下:

html = """
<html><head><title>The Dormouse's story</title></head><body><p class="story">Once upon a time there were three little sisters; and their names were<a href="http://example.com/elsie" class="sister" id="link1"><span>Elsie</span></a></p><p class="story">...</p>
"""
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.a.parent)

運行結果如下:

?

????????在這個例子中,我們選擇的是第一個 a 節點的父節點元素。很明顯,a 節點的父節點是 p 節點,所以輸出結果就是 p 節點及其內部的內容。

????????需要注意的是,這里輸出的僅僅是 a 節點的直接父節點,并沒有再向外尋找父節點的祖先節點。如果我們想要獲取所有的祖先節點,可以調用 parents 屬性:

html = """
<html><body><p class="story"><a href="http://example.com/elsie" class="sister" id="link1"><span>Elsie</span></a></p>
"""
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(type(soup.a.parents))
print(list(enumerate(soup.a.parents)))

運行結果如下:

????????從運行結果可以發現,返回的結果是生成器類型。我們通過將其轉換為列表,并輸出了它的索引和內容,列表中的元素就是 a 節點的祖先節點。

3.4.3 兄弟節點

????????前面我們介紹了子節點和父節點的獲取方式,那么如果要獲取同級的節點,也就是兄弟節點,應該怎么做呢?下面是一個示例:

html = """
<html><body><p class="story">Once upon a time there were three little sisters; and their names were<a href="http://example.com/elsie" class="sister" id="link1"><span>Elsie</span></a>Hello<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a>and<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>and they lived at the bottom of a well.</p>
"""
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print('Next Sibling', soup.a.next_sibling)
print('Prev Sibling', soup.a.previous_sibling)
print('Next Siblings', list(enumerate(soup.a.next_siblings)))
print('Prev Siblings', list(enumerate(soup.a.previous_siblings)))

運行結果如下:

????????這里調用了 4 個屬性,next_siblingprevious_sibling分別用于獲取節點的下一個和上一個兄弟元素。如果目標節點沒有對應的兄弟節點,previous_sibling可能返回None ,就像這里第一個<a>標簽的previous_siblingnext_siblingsprevious_siblings則分別返回后面和前面的兄弟節點集合,返回結果是生成器類型,通過list()函數將其轉換為列表以便查看所有兄弟節點。

3.4.4 提取信息

????????剛才我們講了怎么選擇那些有關聯的元素節點。要是現在想得到這些節點的文本內容、屬性之類的信息,方法和前面介紹的差不多。下面通過例子來說明:?

html = """
<html><body><p class="story">Once upon a time there were three little sisters; and their names were<a href="http://example.com/elsie" class="sister" id="link1">Bob</a><a href="http://example.com/lacie" class="sister" id="link2">Lacie</a></p>
"""
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print('Next Sibling:')
print(type(soup.a.next_sibling))
print(soup.a.next_sibling)
print(soup.a.next_sibling.string)
print('Parent:')
print(type(soup.a.parents))
print(list(soup.a.parents)[0])
print(list(soup.a.parents)[0].attrs['class'])

運行結果:

????????要是選擇節點的返回結果只有一個節點,那直接用string、attrs這些屬性,就能拿到它的文本內容和屬性信息。但要是返回的是一個能生成多個節點的生成器,就得先把它變成列表,從里面挑出想要的元素,接著再用string、attrs屬性,這樣才能得到對應節點的文本和屬性。?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/77010.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/77010.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/77010.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【Docker-13】Docker Container容器

Docker Container&#xff08;容器&#xff09; 一、什么是容器&#xff1f; 通俗地講&#xff0c;容器是鏡像的運行實體。鏡像是靜態的只讀文件&#xff0c;而容器帶有運行時需要的可寫文件層&#xff0c;并且容器中的進程屬于運行狀態。即容器運行著真正的應用進程。容器有…

Spring Cache(筆記)

簡介&#xff1a; 常用注解&#xff1a;

大模型Qwen32b(FP16精度)部署所需的顯存大小和并發數計算分析

大家好&#xff0c;我是微學AI&#xff0c;今天給大家介紹一下大模型Qwen32b(FP16精度)部署所需的顯存大小和并發計算分析。 文章目錄 1. 大模型顯存需求分析1.1 模型參數與顯存占用1.2 不同精度對顯存的影響 2. 不同顯卡配置下的并發能力2.1 80G顯卡并發能力2.2 64G顯卡并發能…

【euclid】10.2 2D變換模塊(transform2d.rs)Arbitrary trait

源碼 #[cfg(feature "arbitrary")] impl<a, T, Src, Dst> arbitrary::Arbitrary<a> for Transform2D<T, Src, Dst> whereT: arbitrary::Arbitrary<a>, {fn arbitrary(u: &mut arbitrary::Unstructured<a>) -> arbitrary::Res…

MAC Mini M4 上測試Detectron2 圖像識別庫

斷斷續續地做圖像識別的應用&#xff0c;使用過各種圖像識別算法&#xff0c;一開始使用openCV 做教室學生計數的程序。以后又使用YOLO 做醫學傷口檢測程序。最近&#xff0c;開始使用meta 公司的Detectron2.打算做OCR 文檔結構分析 Detectron2 的開發者是 Meta 的 Facebook AI…

一天時間,我用AI(deepseek)做了一個配色網站

前言 最近在開發顏色搭配主題的相關H5和小程序&#xff0c;想到需要補充一個web網站&#xff0c;因此有了這篇文章。 一、確定需求 向AI要答案之前&#xff0c;一定要清楚自己想要做什么。如果你沒有100%了解自己的需求&#xff0c;可以先讓AI幫你理清邏輯和思路&#xff0c;…

機器視覺用消色差雙合透鏡

光學系統案例&#xff1a;機器視覺用消色差雙合透鏡 一、設計規格 1. 應用場景&#xff1a;專為工業相機成像而設計&#xff0c;工作于可見光波段&#xff0c;旨在滿足該領域對高精度成像的需求。 2. 核心參數&#xff1a; ? 焦距&#xff1a;精確要求達到 50 mm 1%&#…

批量歸一化(Batch Normalization)原理與PyTorch實現

批量歸一化&#xff08;Batch Normalization&#xff09;是加速深度神經網絡訓練的常用技術。本文通過Fashion-MNIST數據集&#xff0c;演示如何從零實現批量歸一化&#xff0c;并對比PyTorch內置API的簡潔實現方式。 1. 從零實現批量歸一化 1.1 批量歸一化函數實現 import t…

feedback

這個文件 lib/pages/feedback/index.dart 是一個反饋/留言表單頁面的實現&#xff0c;主要功能是&#xff1a; 表單收集功能&#xff1a; 真實姓名&#xff08;必填&#xff09;聯系電話&#xff08;必填&#xff0c;需要驗證手機號格式&#xff09;電子郵箱&#xff08;選填&a…

數據倉庫標準庫模型架構相關概念淺講

數據倉庫與模型體系及相關概念 數據倉庫與數據庫的區別可參考&#xff1a;數據庫與數據倉庫的區別及關系_數據倉庫和數據庫-CSDN博客 總之&#xff0c;數據庫是為捕獲數據而設計&#xff0c;數據倉庫是為分析數據而設計 數據倉庫集成工具 在一些大廠中&#xff0c;其會有自…

適用于 HAL 的 AIDL

目錄 設計初衷 注意 編寫AIDLHAL接口 查找AIDLHAL接口 擴展接口 將現有HAL從HIDL轉換為AIDL AIDL與HIDL之間的主要差異 針對HAL的供應商測試套件(VTS)測試 Android 11 中引入了在 Android 中使用 AIDL 實現 HAL 的功能, 從而可以在不使用 HIDL 的情況下實現 Android 的部分…

leetcode0547. 省份數量-medium

1 題目&#xff1a;省份數量 官方標定難度&#xff1a;中 有 n 個城市&#xff0c;其中一些彼此相連&#xff0c;另一些沒有相連。如果城市 a 與城市 b 直接相連&#xff0c;且城市 b 與城市 c 直接相連&#xff0c;那么城市 a 與城市 c 間接相連。 省份 是一組直接或間接相…

【專題刷題】雙指針(一)

&#x1f4dd;前言說明&#xff1a; 本專欄主要記錄本人的基礎算法學習以及LeetCode刷題記錄&#xff0c;按專題劃分每題主要記錄&#xff1a;1&#xff0c;本人解法 本人屎山代碼&#xff1b;2&#xff0c;優質解法 優質代碼&#xff1b;3&#xff0c;精益求精&#xff0c;…

WebSocket 技術詳解

引言 在現代Web應用中&#xff0c;實時通信已經成為不可或缺的一部分。想象一下聊天應用、在線游戲、股票交易平臺或協作工具&#xff0c;這些應用都需要服務器能夠即時將更新推送給客戶端&#xff0c;而不僅僅是等待客戶端請求。WebSocket技術應運而生&#xff0c;它提供了一…

【redis】初識redis

初識redis Redis 是一種基于鍵值對&#xff08;key-value&#xff09; 的 NoSQL 的數據庫&#xff0c;它與很多鍵值數據庫不同&#xff0c; Redis 中的值可以是 string&#xff08;字符串&#xff09; 、hash&#xff08;哈希&#xff09;、list&#xff08;鏈表&#xff09;、…

UE5 制作方塊邊緣漸變邊框效果

該效果基于之前做的&#xff08;https://blog.csdn.net/grayrail/article/details/144546427&#xff09;進行修改得到&#xff0c;思路也很簡單&#xff1a; 1.打開實時預覽 1.為了制作時每個細節調整方便&#xff0c;勾選Live Update中的三個選項&#xff0c;開啟實時預覽。…

基于springboot的“嗨玩旅游網站”的設計與實現(源碼+數據庫+文檔+PPT)

基于springboot的“嗨玩旅游網站”的設計與實現&#xff08;源碼數據庫文檔PPT) 開發語言&#xff1a;Java 數據庫&#xff1a;MySQL 技術&#xff1a;springboot 工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系統展示 系統功能結構圖 局部E-R圖 系統首頁界面 系統注冊…

grafana/loki 部署搜集 k8s 集群日志

grafana/loki 和 grafana/loki-stack 的區別 ?Grafana 提供了多個 Helm Chart 用于在 Kubernetes 集群中部署 Loki 及相關組件,其中主要包括 grafana/loki 和 grafana/loki-stack。?它們的主要區別如下:? 1.grafana/loki Helm Chart: 專注于 Loki 部署: 該 Chart 專門…

Nacos-Controller 2.0:使用 Nacos 高效管理你的 K8s 配置

作者&#xff1a;濯光、翼嚴 Kubernetes 配置管理的局限 目前&#xff0c;在 Kubernetes 集群中&#xff0c;配置管理主要通過 ConfigMap 和 Secret 來實現。這兩種資源允許用戶將配置信息通過環境變量或者文件等方式&#xff0c;注入到 Pod 中。盡管 Kubernetes 提供了這些強…

python自動化瀏覽器標簽頁的切換

#獲取全部標簽頁的句柄返回句柄的列表 handleswebdriver.window_handles#獲取全部標簽頁的句柄返回句柄的列表 print(len(handles)) 切換標簽頁 handleswebdriver.window_handles webdriver.switch_to.window(handles[index])#切換到第幾個標簽頁就寫幾 關閉標簽頁 關閉標…