Python Requests 網頁爬蟲入門:從 HTTP 請求到資料擷取完整教學
寫程式最爽的事之一,就是讓電腦幫你做那些重複到想翻桌的事情。每天手動去網站複製貼上資料?不用了,寫支爬蟲十分鐘搞定。這篇文章帶你從零開始,用 Python 的 Requests 套件搭配 BeautifulSoup,打造一支能自動抓取網頁資料的爬蟲程式。
如果你還沒碰過 Python 自動化,建議先看看Python 自動化入門完整指南,會對整體概念更有感覺。
什麼是網頁爬蟲?
網頁爬蟲(Web Scraping)說穿了就是三個步驟:
- 發送請求:你的程式假裝是瀏覽器,向目標網站發出 HTTP 請求
- 解析回應:拿到 HTML 原始碼後,用解析器把結構拆開
- 擷取資料:從解析後的結構中,撈出你要的欄位(標題、價格、連結等)
聽起來簡單,實際上也真的不難——至少靜態網頁是這樣。動態渲染的網站就需要用到 Selenium 動態爬蟲,但那是後話了。
環境準備與套件安裝
開始之前,確保你有一個乾淨的 Python 環境。強烈建議用虛擬環境隔離專案相依套件,可以參考Python 虛擬環境教學來設定。
如果你想用更現代的套件管理工具,uv 套件管理器是個不錯的選擇,安裝速度快到飛起來。
安裝我們需要的兩個套件:
pip install requests beautifulsoup4確認安裝成功:
python -c "import requests, bs4; print(requests.__version__, bs4.__version__)"看到版本號就代表沒問題了。
HTTP 請求基礎:GET 與 POST
Requests 是 Python 生態系中最受歡迎的 HTTP 客戶端套件,API 設計簡潔到讓人感動。
GET 請求
最基本的用法,就是對一個 URL 發送 GET 請求:
import requests
response = requests.get('https://httpbin.org/get')
print(response.status_code) # 200
print(response.text) # 回應內容加上查詢參數和自訂 Headers:
params = {'q': 'python web scraping', 'page': 1}
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
}
resp = requests.get(
'https://httpbin.org/get',
params=params,
headers=headers
)
print(resp.url) # 完整的 URL(含參數)
print(resp.json()) # 如果回應是 JSON 格式設定 User-Agent 這件事很重要,很多網站會檢查這個 header,用預設值(python-requests/x.x.x)直接被擋的機率很高。
POST 請求
需要送出表單資料或 JSON 時用 POST:
# 表單資料
resp = requests.post('https://httpbin.org/post', data={'username': 'demo', 'password': '1234'})
# JSON 格式
import json
resp = requests.post(
'https://httpbin.org/post',
json={'query': 'python requests tutorial'},
headers={'Content-Type': 'application/json'}
)用 json= 參數會自動幫你序列化並設定 Content-Type,比手動處理方便得多。
BeautifulSoup 解析 HTML
拿到 HTML 之後,需要把它解析成可操作的結構。BeautifulSoup 就是幹這件事的:
from bs4 import BeautifulSoup
html = '<html><body><h1 class="title">Hello</h1><p>World</p></body></html>'
soup = BeautifulSoup(html, 'html.parser')
# 找單一元素
h1 = soup.find('h1')
print(h1.text) # Hello
print(h1['class']) # ['title']
# 找所有符合的元素
all_p = soup.find_all('p')
for p in all_p:
print(p.text)CSS 選擇器
如果你熟悉前端,用 CSS 選擇器會更直覺:
# select 回傳 list,select_one 回傳單一元素
titles = soup.select('h1.title')
links = soup.select('a[href^="https"]')
first_item = soup.select_one('.item:first-child')我個人比較偏好用 select,因為語法跟寫 CSS 一模一樣,切換成本為零。
實戰練習:爬取新聞標題
來個實際的例子。我們來爬 Hacker News(news.ycombinator.com)的首頁標題:
import requests
from bs4 import BeautifulSoup
def scrape_hacker_news():
url = 'https://news.ycombinator.com/'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
}
resp = requests.get(url, headers=headers, timeout=10)
resp.raise_for_status() # 非 2xx 狀態碼就拋例外
soup = BeautifulSoup(resp.text, 'html.parser')
# Hacker News 的標題在 .titleline > a 裡面
items = soup.select('.titleline > a')
results = []
for item in items:
results.append({
'title': item.text,
'url': item.get('href', '')
})
return results
# 執行爬蟲
news = scrape_hacker_news()
for i, item in enumerate(news[:10], 1):
print(f"{i}. {item['title']}")
print(f" {item['url']}")短短不到 30 行程式碼,你就有一支能抓取 Hacker News 標題的爬蟲了。抓下來的資料可以用 Pandas 做進一步的整理和分析。
錯誤處理與反爬蟲對策
真實世界的爬蟲跟教學範例最大的差別,就是要處理各種意外狀況。
指數退避重試
網路不穩或伺服器暫時超載時,不要傻傻地一直重送,用指數退避(exponential backoff):
import time
import requests
def fetch_with_retry(url, max_retries=3):
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
}
for attempt in range(max_retries):
try:
resp = requests.get(url, headers=headers, timeout=10)
resp.raise_for_status()
return resp
except requests.RequestException as e:
wait = 2 ** attempt # 1, 2, 4 秒
print(f"第 {attempt + 1} 次失敗:{e},{wait} 秒後重試...")
time.sleep(wait)
raise Exception(f"重試 {max_retries} 次後仍然失敗")尊重 Rate Limiting
別把人家伺服器當成你家的——在每次請求之間加個延遲:
import time
import random
def polite_scrape(urls):
results = []
for url in urls:
resp = fetch_with_retry(url)
results.append(resp.text)
# 隨機延遲 1~3 秒,模擬人類行為
time.sleep(random.uniform(1, 3))
return resultsSession 與 Cookies
需要維持登入狀態或 cookies 時,用 Session 物件:
session = requests.Session()
session.headers.update({'User-Agent': 'Mozilla/5.0 ...'})
# 第一次請求會拿到 cookies
session.get('https://example.com/')
# 後續請求自動帶上 cookies
resp = session.get('https://example.com/dashboard')檢查 robots.txt
在爬任何網站之前,先看一下它的 robots.txt:
resp = requests.get('https://example.com/robots.txt')
print(resp.text)裡面會寫明哪些路徑允許爬取、哪些禁止,以及建議的爬取間隔。遵守 robots.txt 是基本禮貌,也能避免法律糾紛。
爬蟲的道德與法律注意事項
寫爬蟲很有趣,但別忘了幾個重要原則:
- 遵守 robots.txt:這是網站主人設定的爬取規則,務必尊重
- 控制請求頻率:別對目標伺服器造成過大負擔,加上合理的延遲
- 不要爬取個人隱私資料:即使技術上做得到,也不代表你應該這麼做
- 注意網站的使用條款:有些網站明確禁止自動化存取
- 資料用途要合法:爬下來的資料如果拿去商業使用或重新發布,可能會有法律問題
簡單說:能爬不代表該爬,技術能力伴隨著責任。
進階:下一步學什麼?
學會 Requests + BeautifulSoup 之後,你已經能處理大部分靜態網頁的資料擷取需求了。接下來可以往這幾個方向發展:
- 動態網頁爬蟲:碰到 JavaScript 渲染的網站,就需要用 Selenium 動態爬蟲來處理
- 排程自動執行:用 APScheduler 讓爬蟲定期自動執行
- 資料分析:爬回來的資料用 Pandas 做清洗和分析
- 建立 API:把爬到的資料透過 FastAPI 包裝成 REST API 提供給其他服務使用
爬蟲只是自動化的起點。當你能穩定地從各種來源擷取資料,再搭配資料分析和 API 開發的能力,就能打造出非常強大的資料管線(data pipeline)。
寫爬蟲跟寫其他程式一樣,多練就對了。找個你有興趣的網站,動手爬看看吧。
繼續閱讀
Python AI Agent 開發入門:用 LangChain 打造你的第一個自動化智能助手
相關文章
你可能也喜歡
探索其他領域的精選好文