專項練習 · 9 分鐘閱讀

Python 爬蟲練習:搭建禮貌的抓取流水線

爬蟲是一條流水線,不是一次請求。這些練習把抓取、解析、提取和儲存分開,讓每個階段都能在不存取真實網站的情況下測試。

從儲存的頁面開始

開發時下載一次,把 HTML 儲存下來,然後反覆解析這個樣本。這樣偵錯時不受網路波動影響,也方便測試缺失屬性、重複連結等邊界情況。

from html.parser import HTMLParser

class Links(HTMLParser):
    def __init__(self):
        super().__init__()
        self.links = []
    def handle_starttag(self, tag, attrs):
        href = dict(attrs).get("href")
        if tag == "a" and href:
            self.links.append(href)

p = Links()
p.feed('<a href="/a">A</a><a href="/a">A</a><a href="/b">B</a>')
print(p.links)

可以反覆執行的樣本

單獨構造請求

把請求構造放在一個函式裡。真正發送時設定描述清楚的 User-Agent 和超時。本站的瀏覽器執行器不會發送網路請求,所以這些範例只到 Request 物件為止。

from urllib.request import Request

request = Request(
    "https://example.com/docs",
    headers={"User-Agent": "LearningBot/1.0"},
)
print(request.full_url)
print(request.get_header("User-agent"))

這個範例不聯網

按狀態碼分支

不要把 404 頁面當成目標頁面解析。用一個小函式把狀態判斷集中起來,重試策略也就有了唯一的位置。

def outcome(status):
    if 200 <= status < 300:
        return "parse"
    if 300 <= status < 400:
        return "follow redirect"
    if status == 429:
        return "back off"
    return "stop"

print(outcome(200))
print(outcome(429))

一個小的狀態策略

儲存緊湊的記錄

只提取任務需要的欄位,其餘內容留在原頁面。結構化結果可以用字典列表儲存,並按穩定鍵(例如絕對 URL)去重。寫入檔案或資料庫前,結果應當便於檢查。

rows = [
    {"url": "/a", "title": "A"},
    {"url": "/a", "title": "A"},
    {"url": "/b", "title": "B"},
]
unique = list({row["url"]: row for row in rows}.values())
print(unique)

每個 URL 一條記錄

抓取前先讀規則

robots.txt 只是起點,不是全部協議。閱讀站點條款,表明客戶端身份,限制請求頻率;沒有合法依據時不要收集個人資料。站點明確拒絕時就停止。

robots = "User-agent: *\nDisallow: /private\nCrawl-delay: 2"
rules = {}
for line in robots.splitlines():
    if ":" in line:
        key, value = line.split(":", 1)
        rules[key.strip().lower()] = value.strip()
print(rules["disallow"])
print(rules["crawl-delay"])

最小但必要的檢查

你的練習清單

常見問題

瀏覽器執行器能抓真實網站嗎?

不能。課程執行器用於本機 Python 範例,不會發送任意網路請求。真實抓取應在受控的 Python 環境執行。

應該用 requests 還是 urllib?

兩者都可以。urllib 屬於標準函式庫;requests 是常用的第三方封裝。解析和合規規則相同。

網站阻止我時怎麼辦?

停止。不要繞過登入、驗證碼、付費牆或存取控制。應尋找 API 或申請許可。

練習爬蟲流水線

12 道題,覆蓋請求、HTML 解析、去重和禮貌抓取限制。

打開練習

繼續閱讀: