BeautifySoup 模組
Python 的 Beautiful Soup 模組是一個用來解析 HTML 和 XML 文件的程式庫。這個模組提供了一個方便的方式來提取網頁資料,尤其適合於網路爬蟲的開發。Beautiful Soup 透過轉換複雜的 HTML 文件為一個複雜的樹狀結構,讓程式師能夠輕鬆地存取各個 HTML 標籤和屬性。
HTML 結構
在開始介紹 BeautifySoup 模組使用前,先來快速複習一下,HTML相關知識。
HTML (HyperText Markup Language) 是用於建立網頁的標準標記語言。HTML 文件由一系列元素構成,這些元素通過標籤來定義。一個基本的 HTML 文件結構包括以下部分:
- 文檔類型聲明(Doctype): 這是一行非 HTML 代碼,它告訴瀏覽器文件的 HTML 版本。例如,HTML5 的文檔類型聲明是
<!DOCTYPE html>
。 - HTML 標籤: 文件的開始和結束由
<html>
和</html>
標籤標記。這些標籤包含了整個 HTML 文件的內容。 - Head 區塊: 由
<head>
和</head>
標籤包裹,包含了文檔的元數據,如<title>
標籤(定義網頁標題)和鏈接到外部文件的<link>
標籤(常用於鏈接 CSS 文件)。 - Body 區塊: 由
<body>
和</body>
標籤包裹,包含了網頁的所有內容,如文本、圖片、超連結、表格、列表等。 - 標籤: HTML 標籤是由尖括號包圍的關鍵字,如
<p>
(段落)和<a>
(超連結)。大多數標籤有匹配的關閉標籤,如<p></p>
。 - 屬性: 標籤可以包含屬性,屬性提供了關於 HTML 元素的額外資訊。例如,
<a href="https://www.example.com">
中的href
就是一個屬性,指定了連結的目標 URL。 - 註釋: 使用
<!-- 註釋內容 -->
來添加註釋,這些註釋不會在瀏覽器中顯示。
一個簡單的 HTML 文件示例可能如下所示:
<!DOCTYPE html>
<html>
<head>
<title>網頁標題</title>
</head>
<body>
<h1>這是一個標題</h1>
<p>這是一個段落。</p>
<a href="https://www.example.com">這是一個超連結</a>
</body>
</html>
這個結構基礎上構成了大多數網頁的框架,而更複雜的功能(如互動性、佈局控制等)則需要 CSS (Cascading Style Sheets) 和 JavaScript 的輔助。
結構區塊標籤
及其用途:
標籤 | 用途 | 說明 |
---|---|---|
<html> | HTML 文件的根元素 | 包含整個 HTML 文檔的內容。 |
<head> | 文檔的頭部區域 | 包含了文檔的元數據,如 CSS 樣式鏈接、JavaScript 文件等。 |
<title> | 定義文檔的標題 | 在瀏覽器的標題欄或頁籤上顯示。 |
<meta> | 提供有關 HTML 文檔的元數據 | 用於指定頁面描述、關鍵詞、文檔作者、字符集等。 |
<link> | 鏈接外部資源 | 用於鏈接外部資源,如 CSS 樣式表。 |
<script> | 定義客戶端腳本(如 JavaScript) | 用於在 HTML 文檔中嵌入或引用 JavaScript 代碼。 |
<body> | 文檔的主體區域 | 包含網頁的所有可見內容,如文本、圖片、超連結等。 |
<div> | 區塊元素 | 用於創建一個邏輯容器,常用於 CSS 布局或 JavaScript 操作的目的。 |
顯示類標籤
及其用途
標籤 | 用途 | 說明 |
---|---|---|
<h1> 到 <h6> | 標題標籤 | 用於定義 HTML 標題,<h1> 是最大的標題,<h6> 是最小的標題。 |
<p> | 段落標籤 | 用於定義文本的段落。 |
<span> | 行內元素 | 類似於 <div>,但用於行內元素的分組。 |
<br> | 換行 | 在文本中插入一個換行,常用於段落或長文本內部。 |
<b> | 粗體文本 | 使包含的文本顯示為粗體。 |
<i> | 斜體文本 | 使包含的文本顯示為斜體。 |
<strong> | 強調文本 | 使文本成為粗體,表示它的重要性更高。 |
<em> | 強調文本 | 使文本變為斜體,表示強調。 |
<a> | 超連結標籤 | 用於定義超連結,可以鏈接到不同的頁面或頁面內的某個部分。 |
<blockquote> | 引用區塊 | 用於定義長的引用,通常有縮進樣式。 |
<pre> | 預格式化的文本區塊 | 用於顯示預格式化的文本,保留空格和換行。 |
<code> | 程式碼 | 用於顯示一段程式碼,通常與 <pre> 標籤結合使用。 |
<img> | 圖片標籤 | 用於在網頁中嵌入圖片。 |
<iframe> | 內嵌框架 | 用於在當前文檔中嵌入另一個文檔,如嵌入 YouTube 影片、地圖等。 |
顯示範例
<!DOCTYPE html>
<html>
<head>
<title>顯示類標籤範例</title>
</head>
<body>
<h1>歡迎來到我的網頁</h1>
<p>這是一個段落,展示了如何使用 <b>粗體</b> 和 <i>斜體</i> 文本。</p>
<div style="border:1px solid black; padding:10px;">
<h2>區塊級元素示例</h2>
<p>這是一個 <code>div</code> 元素的示例,用於創建一個帶邊框的區塊。</p>
</div>
<p>以下是一段預格式化的文本:</p>
<pre>
function sayHello() {
console.log("Hello, world!");
}
</pre>
<p>引用示例:</p>
<blockquote>這是一個引用區塊,用於引用長段文字。</blockquote>
<p>圖片展示:</p>
<img src="example.jpg" alt="示例圖片" />
<p>行內元素 <span style="color:red;">紅色文字</span> 示例。</p>
</body>
</html>
列表類型標籤
及其用途
標籤 | 用途 | 說明 |
---|---|---|
<ul> | 無序列表 | 用於創建無序列表,通常與 <li>(列表項目)標籤一起使用。 |
<ol> | 有序列表 | 用於創建有序列表,也與 <li> 標籤一起使用。 |
<li> | 列表項目 | 用於 <ul> 或 <ol> 內部,表示單個列表項目。 |
<dl> | 定義列表 | 用於創建一個定義列表,通常包括一組術語和其定義。 |
<dt> | 定義列表中的術語 | 用於 <dl> 內,指定一個需要解釋或定義的術語。 |
<dd> | 定義列表中的術語定義 | 用於 <dl> 內,跟隨 <dt> 元素,提供對應術語的定義或解釋。 |
列表範例
<!DOCTYPE html>
<html>
<head>
<title>列表標籤範例</title>
</head>
<body>
<h2>無序列表範例</h2>
<ul>
<li>蘋果</li>
<li>橘子</li>
<li>香蕉</li>
</ul>
<h2>有序列表範例</h2>
<ol>
<li>第一步</li>
<li>第二步</li>
<li>第三步</li>
</ol>
<h2>定義列表範例</h2>
<dl>
<dt>HTML</dt>
<dd>超文本標記語言</dd>
<dt>CSS</dt>
<dd>層疊樣式表</dd>
</dl>
</body>
</html>
表單類型標籤
及其用途
標籤 | 用途 | 說明 |
---|---|---|
<form> | 表單標籤 | 用於創建 HTML 表單以收集用戶輸入。 |
<fieldset> | 字段集合 | 用於將相關元素分組並構建表單的結構。 |
<legend> | 字段集合標題 | 與 <fieldset> 元素一起使用,為字段集合提供標題。 |
<input> | 輸入控件 | 用於創建不同類型的輸入元素,如文本框、復選框、按鈕等。 |
<textarea> | 多行文本輸入框 | 用於 <form> 內,創建一個多行文本輸入框。 |
<label> | 標籤 | 定義 <input> 元素的標籤,提高可訪問性,通常與 for 屬性一起使用。 |
<select> | 下拉選單 | 用於 <form> 內,創建一個下拉選單,選項使用 <option> 標籤表示。 |
<option> | 下拉選單中的選項 | 用於 <select> 內,定義下拉選單中的一個選項。 |
<button> | 按鈕 | 用於創建一個可點擊的按鈕,可以包含文本或圖像。 |
<input type=”submit”> | 提交按鈕 | 用於提交表單的按鈕,當點擊時,表單數據會被發送到服務器。 |
表單範例
<!DOCTYPE html>
<html>
<head>
<title>表單範例</title>
</head>
<body>
<form action="/submit_form" method="post">
<fieldset>
<legend>個人資訊</legend>
<label for="name">姓名:</label>
<input type="text" id="name" name="name"><br><br>
<label for="email">電子郵件:</label>
<input type="email" id="email" name="email"><br><br>
<label for="job">職業:</label>
<select id="job" name="job">
<option value="student">學生</option>
<option value="teacher">老師</option>
<option value="engineer">工程師</option>
<option value="other">其他</option>
</select><br><br>
<input type="submit" value="提交">
</fieldset>
</form>
</body>
</html>
表格類型標籤
及其用途
標籤 | 用途 | 說明 |
---|---|---|
<table> | 表格標籤 | 用於創建表格,與 <tr>(行)、<td>(單元格)等標籤一起使用。 |
<thead> | 表格頭部區域 | 用於將表格的頭部行(通常包含 <th> 元素)劃分為一個單獨的區域。 |
<th> | 表格中的標題單元格 | 用於 <tr> 內,定義表格的標題單元格,文本預設為加粗和居中。 |
<tbody> | 表格主體區域 | 用於將表格的主體內容(通常包含多個 <tr>)劃分為一個單獨的區域。 |
<tr> | 表格中的行 | 用於 <table> 內,定義表格的一行。 |
<td> | 表格中的單元格 | 用於 <tr> 內,定義表格的一個單元格。 |
表格範例
<!DOCTYPE html>
<html>
<head>
<title>表格範例</title>
</head>
<body>
<table border="1">
<caption>課程表</caption>
<thead>
<tr>
<th>時間</th>
<th>星期一</th>
<th>星期二</th>
<th>星期三</th>
<th>星期四</th>
<th>星期五</th>
</tr>
</thead>
<tbody>
<tr>
<td>9:00-10:00</td>
<td>數學</td>
<td>英語</td>
<td>物理</td>
<td>化學</td>
<td>體育</td>
</tr>
<tr>
<td>10:00-11:00</td>
<td>地理</td>
<td>歷史</td>
<td>生物</td>
<td>音樂</td>
<td>美術</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="6">註:每天都有20分鐘的休息時間</td>
</tr>
</tfoot>
</table>
</body>
</html>
這些標籤構成了 HTML 文檔的基本結構和內容,根據需要選擇合適的標籤來組織和呈
常見的 HTML 屬性
及其用法:
屬性 | 適用標籤 | 說明 | 範例 |
---|---|---|---|
id | 所有標籤 | 指定元素的 唯一標識符 。 | <div id=”uniqueid”></div> |
class | 所有標籤 | 指定元素的類名,常用於 CSS 和 JavaScript。 | <div class=”classname”></div> |
style | 所有標籤 | 直接在元素上應用 CSS 樣式。 | <p style=”color: red;”>紅色文字</p> |
title | 所有標籤 | 提供有關元素的額外資訊,通常以工具提示形式顯示。 | <p title=”提示信息”>懸停查看提示</p> |
href | <a> | 指定超連結的目標 URL。 | <a href=”https://www.example.com”>連結</a> |
src | <img> | 指定圖像文件的路徑。 | <img src=”image.jpg” alt=”描述”> |
alt | <img> | 為圖像提供替代文本。 | <img src=”image.jpg” alt=”描述”> |
name | <input> | 為輸入元素指定名稱。 | <input type=”text” name=”username”> |
type | <input> | 定義輸入元素的類型(如 text, radio)。 | <input type=”checkbox”> |
placeholder | <input> | 提供輸入欄位的提示文字。 | <input type=”text” placeholder=”姓名”> |
value | <input> | 定義輸入控件的初始值。 | <input type=”submit” value=”提交”> |
disabled | <input> | 指定輸入元素應該被禁用。 | <input type=”text” disabled> |
checked | <input> | 指定復選框或單選按鈕初始狀態為選中。 | <input type=”checkbox” checked> |
readonly | <input> | 指定輸入欄位為只讀。 | <input type=”text” readonly> |
rows | <textarea> | 指定多行文本輸入的行數。 | <textarea rows=”4″></textarea> |
cols | <textarea> | 指定多行文本輸入的列數。 | <textarea cols=”50″></textarea> |
這些屬性是 HTML 元素常用的配置選項,能夠幫助開發者控制元素的行為和外觀。正确使用這些屬性可以使網頁更加功能豐富和用戶友好。
使用 Beautiful Soup 的基本步驟
- 安裝:首先需要安裝 Beautiful Soup。一般來說,可以通過 Python 的包管理工具 pip 安裝,如執行
pip install beautifulsoup4
。 - 導入模組:在 Python 程式中,導入 Beautiful Soup 模組,通常還會搭配
requests
模組來發送網路請求。例如:from bs4 import BeautifulSoup
。 - 獲取和解析網頁:使用
requests
模組獲取網頁內容,然後用 Beautiful Soup 解析這些內容。例如:import requests from bs4 import BeautifulSoup response = requests.get('網址') soup = BeautifulSoup(response.content, 'html.parser')
- 提取數據:一旦獲取了解析後的 HTML,就可以使用 Beautiful Soup 提供的各種方法來提取需要的數據。例如,使用
soup.find_all()
來查找所有符合特定條件的標籤。 - 處理數據:提取的數據可以進一步處理或存儲,以符合程式的需求。
HTML 解析器
Beautiful Soup 支援多種解析器,如 html.parser
、lxml
和 html5lib
,每個解析器有其特點,可以根據具體需求選擇使用。此外,Beautiful Soup 也提供了豐富的文檔和社群支援,方便程式師學習和使用。
以下是一些常見解析器的比較:
- Python 標準庫的
html.parser
:- 優點:不需要安裝額外的 Python 庫,即可使用。
- 缺點:可能不如其他外部解析器那麼快速或健壯。在異常的 HTML 結構處理上可能不夠準確。
- 使用場景:適合簡單的 HTML 解析任務,特別是當避免外部依賴是一個要求時。
lxml
HTML 解析器:- 優點:非常快速,解析效率高。對異常的 HTML 處理較好。
- 缺點:需要安裝外部的
lxml
庫。 - 使用場景:適合需要處理大量或複雜 HTML 文件的場景,尤其是在性能是關鍵考量因素時。
lxml
的 XML 解析器:- 優點:與
lxml
的 HTML 解析器相同,特別適合於解析 XML 文件。 - 缺點:需要安裝
lxml
。 - 使用場景:當處理純 XML 數據時最為適合。
- 優點:與
html5lib
:- 優點:極高的標準準確性,能夠像瀏覽器那樣解析 HTML,包括非常異常的或破碎的標記。
- 缺點:速度較慢,需要安裝
html5lib
库。 - 使用場景:適合需要與瀏覽器解析方式非常接近的場景,尤其是處理不規範或破碎的 HTML 時。
選擇哪個解析器取決於具體需求:如果需要快速解析,lxml
是一個好選擇;如果對解析準確性有高要求,尤其是處理不規範的 HTML,html5lib
更為合適;如果想避免安裝外部依賴,則可以使用 Python 標準庫的 html.parser
。
解析器 | 使用方法 | 優點 | 缺點 | 適用情況 |
---|---|---|---|---|
Python 標準庫的 html.parser | BeautifulSoup(markup, “html.parser”) | 不需要安裝額外的庫,內建於 Python 中 | 可能不如其他解析器那麼快或準確 | 適合簡單的 HTML 解析,當避免外部依賴是重要考量時使用 |
lxml 的 HTML 解析器 | BeautifulSoup(markup, “lxml”) | 非常快速,解析效率高 | 需要安裝外部的 lxml 庫 | 處理大量或複雜 HTML 文件,尤其在性能是關鍵考量時 |
lxml 的 XML 解析器 | BeautifulSoup(markup, “lxml-xml”) | 解析 XML 文件時效率高 | 需要安裝 lxml | 專門用於解析 XML 文件 |
html5lib | BeautifulSoup(markup, “html5lib”) | 極高的標準準確性,解析方式類似於瀏覽器,創建有效的 HTML5 | 速度較慢,需要安裝 html5lib | 需要與瀏覽器解析方式非常接近,特別是處理不規範的 HTML 時 |
使用方法
Beautiful Soup 提供了多種方法來簡化 HTML 和 XML 文件的解析和數據提取過程。
以下是一些常用的方法:
- find() 和 find_all():
find()
:找到第一個匹配指定標籤或屬性的元素。find_all()
:找到所有匹配指定標籤或屬性的元素。
first_paragraph = soup.find('p') all_paragraphs = soup.find_all('p')
- select():
- 使用 CSS 選擇器來選取元素。這對於需要更複雜選擇規則的情況特別有用。
articles = soup.select('div.article')
- get_text():
- 從標籤中提取所有文本內容。
text = first_paragraph.get_text()
- attributes(屬性)訪問:
- 直接從標籤中提取屬性,如
href
、id
、class
等。
例如:
link_url = soup.find('a')['href']
- 直接從標籤中提取屬性,如
- children 和 descendants:
children
:獲取直接子元素。descendants
:獲取所有子孫元素。
這些屬性通常用於遍歷元素樹。
- parent 和 parents:
parent
:獲取直接父元素。parents
:獲取所有祖先元素。
- next_sibling 和 previous_sibling:
- 這些方法可以用來訪問同一層級的下一個或上一個元素。
- string:
- 如果標籤只包含文本,則可以使用
string
屬性直接獲取文本內容。
- 如果標籤只包含文本,則可以使用
這些方法通常結合使用,以便更有效地從複雜的 HTML 結構中提取所需的數據。
常用方法
方法名稱 | 使用方式 | 說明 |
---|---|---|
find() | soup.find(‘tag_name’) | 找到第一個匹配指定標籤或屬性的元素。 |
find_all() | soup.find_all(‘tag_name’) | 找到所有匹配指定標籤或屬性的元素。 |
select() | soup.select(‘css_selector’) | 使用 CSS 選擇器來選取元素。 |
get_text() | tag.get_text() | 從標籤中提取所有文本內容。 |
屬性訪問 | tag[‘attribute’] | 直接從標籤中提取屬性,如 href、id、class 等。 |
children | tag.children | 獲取直接子元素。 |
descendants | tag.descendants | 獲取所有子孫元素。 |
parent | tag.parent | 獲取直接父元素。 |
parents | tag.parents | 獲取所有祖先元素。 |
next_sibling | tag.next_sibling | 獲取同一層級的下一個元素。 |
previous_sibling | tag.previous_sibling | 獲取同一層級的上一個元素。 |
string | tag.string | 如果標籤只包含文本,則可以使用此屬性直接獲取文本內容。 |
這些方法可以組合使用,從而更有效地從複雜的 HTML 結構中提取所需的數據。每個方法都有其特定的使用場景,選擇合適的方法可以大大提高數據提取的效率和準確性。
參考資源
- Beautiful Soup 官方文檔 官方文檔是學習 Beautiful Soup 的絕佳資源,它提供了安裝指南、不同解析器的比較,以及如何使用 Beautiful Soup 進行 HTML 和 XML 解析的詳細指導。
- G. T. Wang 的部落格 提供了詳細的 Beautiful Soup 使用教學,涵蓋基本的操作方法,例如使用
find_all
搜尋 HTML 標籤,取出節點屬性,以及限制搜尋節點數量等技巧。 - Python學堂 的教學則涵蓋了從載入 Beautiful Soup 套件,開始導覽網頁局部內容,到更進階的搜尋方法。這個教學提供了多個實用範例,例如如何取出特定元素、搜尋父元素、取得標籤的屬性值等。
- LearnCodeWithMike 的教學提供了七個實用技巧,例如使用
find_all
來搜尋符合特定標籤和 CSS 屬性值的所有節點,或者使用select
方法來透過 CSS 屬性值進行 HTML 節點搜尋。這個教學還介紹了如何搜尋父節點和前後節點,以及如何取得屬性值和連結文字。 - STEAM 教育學習網 的教學則強調了 Beautiful Soup 方法的參數使用,例如
string
、limit
、recursive
等,以及如何使用.get_text()
和屬性索引來輸出內容或屬性。此外,該教學還提供了具體的範例,例如抓取水庫的容量。
這些資源涵蓋了從基礎到進階的 Beautiful Soup 使用技巧,非常適合初學者和需要深入了解的開發者。
您可以根據自己的學習需求選擇合適的教學進行學習。
結論
Beautiful Soup 模組在解析網頁資料方面的便利性不容忽視。它使得從複雜的 HTML 結構中快速提取和整理所需數據成為可能。然而,要充分利用 Beautiful Soup 的強大功能,基本的 HTML 結構、標籤以及屬性的理解是必不可少的。本章節的分享旨在幫助大家掌握這些基礎知識,並理解如何將前一章節介紹的 Requests 模組與 Beautiful Soup 結合使用,從而實現有效的網頁數據抓取和處理。透過這些工具,您將能夠更加靈活地處理網絡資料,為您的項目或數據分析任務帶來便利。
Python基礎系列文章
[Python教學]開發工具介紹
[開發工具] Google Colab 介紹
[Python教學] 資料型態
[Python教學] if判斷式
[Python教學] List 清單 和 Tuple元組
[Python教學] for 和 while 迴圈
[Python教學] Dictionary 字典 和 Set 集合
[Python教學] Dictionary 字典 和 Set 集合
[Python教學] Function 函示
[Python教學] Class 類別
[Python教學] 例外處理
[Python教學] 檔案存取
[Python教學] 實作密碼產生器
[Python教學] 日期時間
[Python教學] 日期時間
[Python教學] 套件管理