Python BeautifulSoup 網頁爬蟲入門教學:從零開始擷取網頁資料完整指南
如果你是 Python 初學者,想要從網路上自動擷取資料,那 BeautifulSoup 絕對是你該學的第一個工具。不管是抓商品價格、新聞標題、還是論壇上的討論串,BeautifulSoup 搭配 Requests 這個組合,基本上能搞定大部分靜態網頁的爬蟲需求。
我自己剛開始學爬蟲的時候,其實繞了不少彎路,一下子看 Scrapy、一下子又去碰 Selenium,搞了半天才發現:先從 BeautifulSoup 入門才是最聰明的選擇。這篇文章就是我當初想看到的那種教學——從零開始,把每一步都講清楚。
什麼是 BeautifulSoup?為什麼要學它?
BeautifulSoup 是一個 Python 的 HTML/XML 解析套件,白話來說,就是幫你把一堆看起來很亂的 HTML 原始碼,變成你可以輕鬆操作的 Python 物件。你可以用它來搜尋特定的標籤、提取文字內容、抓取連結等等。
為什麼推薦新手從它開始?
- 語法超級直覺:find、find_all,看名字就知道在幹嘛
- 文件齊全:官方文件寫得很好,社群資源也多
- 搭配 Requests 就能用:不需要搞一堆複雜設定
- 處理不規則 HTML 的能力很強:真實世界的網頁常常 HTML 寫得很爛,BeautifulSoup 照樣能解析
當然,它也有限制——遇到需要 JavaScript 渲染的動態網頁,就得靠其他工具了。如果你之後有這個需求,可以參考Python Selenium 動態爬蟲教學這篇文章。
安裝 BeautifulSoup 與 Requests
開始之前,先確認你的電腦有裝 Python 3.6 以上的版本。然後打開終端機(Windows 用 CMD 或 PowerShell,Mac 用 Terminal),輸入以下指令:
pip install beautifulsoup4 requests
注意套件名稱是 beautifulsoup4,不是 beautifulsoup(那是舊版的)。另外建議也裝一下 lxml 這個解析器,速度比預設的快不少:
pip install lxml
裝好之後,在 Python 裡面 import 看看有沒有成功:
from bs4 import BeautifulSoup
import requests
print("安裝成功!")
沒有跳錯誤的話,就可以開始了。
第一步:用 Requests 抓取網頁
爬蟲的流程其實很簡單:先用 Requests 把網頁的 HTML 下載回來,再用 BeautifulSoup 去解析裡面的內容。我們先來看第一步:
import requests
url = "https://example.com"
response = requests.get(url)
# 確認請求成功
print(response.status_code) # 200 表示成功
print(response.text[:500]) # 印出前 500 個字元看看
這邊有幾個要注意的地方:
response.status_code回傳 200 代表請求成功,403 可能是被擋了,404 就是頁面不存在response.text是整個網頁的 HTML 原始碼,是一大串字串- 有些網站會擋沒有 User-Agent 的請求,所以建議加上 headers
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
}
response = requests.get(url, headers=headers)
解析 HTML:find、find_all 與 select
拿到 HTML 之後,就可以丟給 BeautifulSoup 來解析了。這是最核心的部分,一定要搞懂。
from bs4 import BeautifulSoup
soup = BeautifulSoup(response.text, "lxml")
# 找第一個符合的標籤
title = soup.find("h1")
print(title.text)
# 找所有符合的標籤
all_links = soup.find_all("a")
for link in all_links:
print(link.get("href"), link.text)
這三個方法你一定要會:
1. find() — 找第一個符合條件的元素
# 找 class 為 "article-title" 的 div
soup.find("div", class_="article-title")
# 找 id 為 "main-content" 的元素
soup.find(id="main-content")
# 找帶有特定屬性的元素
soup.find("a", attrs={"data-type": "external"})
2. find_all() — 找所有符合條件的元素
# 找所有的 p 標籤
paragraphs = soup.find_all("p")
# 限制只找前 5 個
paragraphs = soup.find_all("p", limit=5)
# 同時找多種標籤
headings = soup.find_all(["h1", "h2", "h3"])
3. select() — 用 CSS 選擇器來找
# 如果你熟悉 CSS,select 會讓你覺得很親切
soup.select("div.content > p") # div.content 下的直接子元素 p
soup.select("ul.menu li a") # 巢狀選擇
soup.select("a[href^='https']" ) # 屬性選擇器
我個人比較常用 select(),因為如果你有前端開發的經驗,CSS 選擇器寫起來會更順手。不過 find() 和 find_all() 在處理一些比較特殊的搜尋條件時更靈活。
實戰練習:爬取新聞網站標題與連結
講了這麼多,來個實際的例子吧。我們來爬一個常見的新聞列表頁面結構。大部分新聞網站的文章列表長得差不多,都是一堆 <a> 標籤包在某個容器裡面:
import requests
from bs4 import BeautifulSoup
url = "https://news.ycombinator.com/" # Hacker News 當範例
headers = {"User-Agent": "Mozilla/5.0"}
response = requests.get(url, headers=headers)
soup = BeautifulSoup(response.text, "lxml")
# 找到所有文章標題
articles = soup.select(".titleline > a")
for i, article in enumerate(articles, 1):
title = article.text
link = article.get("href", "無連結")
print(f"{i}. {title}")
print(f" 連結:{link}")
print()
執行之後,你就會看到 Hacker News 首頁所有文章的標題和連結,整齊地印出來。是不是很簡單?
這邊的重點是:你需要先去觀察目標網頁的 HTML 結構,打開瀏覽器的開發者工具(按 F12),看看你要的資料被什麼標籤包住、有什麼 class 或 id,然後再決定用什麼選擇器去抓。
儲存爬取的資料
抓到資料之後,當然要存起來。最常見的做法是存成 CSV 檔案,之後可以用 Excel 開,或是丟進 Python Pandas 做進一步的資料分析。
import csv
# 假設 articles_data 是一個 list of dict
articles_data = []
for article in articles:
articles_data.append({
"title": article.text,
"link": article.get("href", "")
})
# 存成 CSV
with open("articles.csv", "w", newline="", encoding="utf-8-sig") as f:
writer = csv.DictWriter(f, fieldnames=["title", "link"])
writer.writeheader()
writer.writerows(articles_data)
print(f"成功儲存 {len(articles_data)} 筆資料!")
encoding 用 utf-8-sig 是為了讓 Excel 開啟時中文不會變亂碼,這是個小技巧但非常實用。
如果你要存成 JSON,也很簡單:
import json
with open("articles.json", "w", encoding="utf-8") as f:
json.dump(articles_data, f, ensure_ascii=False, indent=2)
常見問題與踩坑經驗
學爬蟲的過程中,你一定會遇到這些問題。先看過一遍,到時候碰到就不會慌:
1. 中文亂碼
最常見的坑。有些網站的編碼不是 UTF-8,Requests 判斷錯誤就會出現亂碼。解法:
# 方法一:手動指定編碼
response.encoding = "utf-8"
# 方法二:讓 Requests 自己猜(通常準確率不錯)
response.encoding = response.apparent_encoding
2. 被網站封鎖(403 Forbidden)
記得加 headers,特別是 User-Agent。如果還是被擋,可能需要加入延遲:
import time
for url in urls:
response = requests.get(url, headers=headers)
# 處理資料...
time.sleep(2) # 每次請求間隔 2 秒,別太頻繁
3. 找不到預期的元素
如果 find 回傳 None,通常有幾個原因:選擇器寫錯了、網頁是動態渲染的(JavaScript 生成的內容抓不到)、或者網頁結構跟你看到的不一樣(有些網站會針對爬蟲回傳不同的 HTML)。
4. 動態網頁抓不到資料
如果網頁內容是透過 JavaScript 才載入的,BeautifulSoup 就束手無策了。這時候你需要用 Selenium 來模擬瀏覽器行為,詳細做法可以看Python Selenium 動態爬蟲教學。
5. 請尊重 robots.txt
這點很重要但常被忽略。在爬任何網站之前,先去看看 https://目標網站/robots.txt,確認哪些路徑是允許爬取的。別當那個讓網站管理員頭痛的人。
下一步:進階爬蟲學習路線
學完 BeautifulSoup 的基礎之後,你可以根據需求往不同方向發展:
- 定時自動執行爬蟲:學會之後想讓爬蟲每天自動跑?可以搭配 Python APScheduler 排程自動化來實現
- 動態網頁爬蟲:遇到 JavaScript 渲染的頁面,就需要 Selenium 了
- 爬取的資料拿來做 API:把爬到的資料包成 API 提供給其他應用使用,可以看看 Python FastAPI 教學
- 大量資料處理:爬到幾萬筆資料之後,用 Pandas 來整理分析會非常有效率
爬蟲是一個入門容易但精通需要時間的技能。不過好消息是,光是 BeautifulSoup + Requests 這個組合,就足以應付你日常 70% 以上的爬蟲需求了。先把基礎打穩,剩下的遇到了再學就好。
最後提醒一下,爬蟲雖然好用,但請遵守網站的使用條款,不要過度頻繁地發送請求,也不要爬取需要登入才能看到的個人隱私資料。做一個有道德的爬蟲工程師,才能在這條路上走得長遠。
繼續閱讀
Python AI Agent 開發入門:用 LangChain 打造你的第一個自動化智能助手
相關文章
你可能也喜歡
探索其他領域的精選好文