引言
Beautiful Soup
是 Python 最流行的 HTML/XML 解析庫,能夠從復雜的網頁文檔中高效提取數據。以下是其核心知識點及示例代碼。
一、庫簡介
1. 核心模塊
- BeautifulSoup:主類,用于構建文檔樹結構
- Tag:表示 HTML/XML 標簽的對象
- NavigableString:標簽內文本內容的特殊字符串類型
- Comment:處理 HTML 注釋的特殊類型
2. 主要特性
- 自動修復不規范文檔
- 支持多種解析器(html.parser, lxml, html5lib)
- 提供 DOM 樹遍歷和搜索方法
二、安裝與基礎使用
1. 安裝
pip install beautifulsoup4 # 安裝 bs4
pip install lxml # 推薦安裝高效解析器
2. 基礎示例
from bs4 import BeautifulSoup# 示例 HTML 文檔
html_doc = """
<html>
<head><title>測試頁面</title></head>
<body>
<div class="content"><h1 id="main-title">網頁標題</h1><p class="text">第一段文字</p><p class="text special">特殊段落</p><a href="https://example.com">示例鏈接</a>
</div>
</body>
</html>
"""# 創建 BeautifulSoup 對象(指定解析器)
soup = BeautifulSoup(html_doc, 'lxml')# 獲取標題文本
title = soup.title.string
print("頁面標題:", title) # 輸出: 測試頁面
三、核心操作示例
1. 標簽查找
# 查找第一個 div 標簽
div_tag = soup.find('div')
print("Div 類名:", div_tag['class']) # 輸出: ['content']# 查找所有 p 標簽
p_tags = soup.find_all('p')
for i, p in enumerate(p_tags, 1):print(f"段落{i}:", p.text)
2. CSS 選擇器
# 選擇類名為 "text" 的所有元素
text_elements = soup.select('.text')
print("找到的文本元素數量:", len(text_elements)) # 輸出: 2# 選擇 id 為 main-title 的元素
title = soup.select_one('#main-title')
print("主標題:", title.text) # 輸出: 網頁標題
3. 屬性操作
# 獲取鏈接的 href 屬性
link = soup.find('a')
print("鏈接地址:", link['href']) # 輸出: https://example.com# 修改標簽屬性
link['target'] = '_blank'
print("修改后的鏈接標簽:", link)
4. 文檔樹導航
# 父子節點操作
body_tag = soup.body
print("Body 的直接子節點數量:", len(list(body_tag.children))) # 輸出: 3(含空白文本節點)# 兄弟節點查找
first_p = soup.find('p')
next_p = first_p.find_next_sibling('p')
print("下一個段落的類名:", next_p['class']) # 輸出: ['text', 'special']
5. 文本處理
# 獲取所有文本內容(合并結果)
full_text = soup.get_text()
print("完整文本:", full_text.strip())# 處理注釋
comment_html = "<p>這是一段<!-- 這是注釋 -->測試文本</p>"
comment_soup = BeautifulSoup(comment_html, 'lxml')
comment = comment_soup.p.next_element.next_element
print("注釋內容:", comment) # 輸出: 這是注釋
四、高級應用示例
1. 提取表格數據
table_html = """
<table><tr><th>姓名</th><th>年齡</th></tr><tr><td>張三</td><td>25</td></tr><tr><td>李四</td><td>30</td></tr>
</table>
"""table_soup = BeautifulSoup(table_html, 'lxml')
rows = table_soup.find_all('tr')# 提取表格數據到字典列表
data = []
for row in rows[1:]: # 跳過表頭cols = row.find_all('td')data.append({'name': cols[0].text,'age': int(cols[1].text)})print("表格數據:", data)
2. 處理嵌套結構
# 多層嵌套選擇
nested_html = """
<div class="article"><div class="header"><h2>文章標題</h2><div class="meta">2023-08-01</div></div><div class="content"><p>正文內容...</p></div>
</div>
"""nested_soup = BeautifulSoup(nested_html, 'lxml')
meta = nested_soup.select('.article > .header > .meta')
print("發布日期:", meta[0].text) # 輸出: 2023-08-01
五、注意事項
-
解析器選擇:
html.parser
:Python 內置,速度一般lxml
:速度快,需要額外安裝html5lib
:容錯性最好,速度最慢
-
編碼處理:
# 顯式指定編碼 soup = BeautifulSoup(html_content, 'lxml', from_encoding='utf-8')
-
動態內容處理:
- 對于 JavaScript 渲染的頁面,需要配合 Selenium 或 Requests-HTML 使用
官方文檔:https://www.crummy.com/software/BeautifulSoup/bs4/doc/