站点被蜘蛛抓得太猛、服務器扛不住时,很多人的第一反應是在網關加一條規則,把超出阈值的請求一律拒掉。结果是蜘蛛收到的既不是“稍後再来”,也不是“頁面没了”,而是一個模糊的错誤。這里只说一件事:当你确實需要给蜘蛛限速时,怎么回應才不至于让它誤判站点狀態。
先分清 429、503 和 403
三個狀態碼在日誌里都像“拒绝”,但對蜘蛛的含义完全不同。
- 429 Too Many Requests:請求數量超了,服務器本身是好的。语义是“你現在太快,等會儿再来”。
- 503 Service Unavailable:服務暂时不可用,通常是维護或過载。蜘蛛一般會放缓节奏並稍後重试。
- 403 Forbidden:明确不允许訪問。用错地方,等于告诉蜘蛛這個 URL 以後別再来了。
把 429 和 403 混用是常见問题:前者是节奏問题,後者是權限問题,蜘蛛的處理方式差別很大。
Retry-After 是给蜘蛛的計时器
429 和 503 都可以带上 Retry-After 响應头,值可以是秒數,也可以是 HTTP 日期。寫了這個头,蜘蛛至少有明确的重试時間參考;不寫,它只能按自己的退避经驗去猜。
如果只是短时限速,给一個具体秒數通常比留空更有帮助,比如 60 或 300。
但不要给出過長的值。寫成 86400,含义接近“一天別来”,實际效果是把相關目錄往後推,和主動降低抓取频次没多大区別。
長期返回 429 會怎样
蜘蛛會记錄站点的响應歷史。如果某個目錄長期返回 429,它通常會降低该目錄的抓取频次,把配額挪去別處。這個過程是渐進的,不會立刻停抓,但恢复起来也不快。
所以限速尽量做成分目錄、分類型的:慢接口、站内搜尋、導出接口單獨限速,正文頁保持正常。全站一刀切,最後被压住的往往是真正需要被抓的頁面。
几個常见的誤用
- 把 429 当成反爬的萬能開關,正常蜘蛛被挡住,自動化脚本照样跑。
- 依赖 robots.txt 里的 Crawl-delay 限速,主流蜘蛛並不嚴格遵循,寫了只是心里安慰。
- 限速只加在 CDN 邊缘,回源依然被压垮,問题只是往後推了一环。
- 接口本身慢導致的超时,用 429 掩盖過去,蜘蛛看到的是限速,不是你真實的故障。
比限速更划算的是先减负
在動手寫限速規則之前,先看响應時間分布:是資料库查询慢,還是模板渲染慢,還是同一时刻並發太高。加一层頁面缓存、给列表頁做静態化、把重查询的接口挪到獨立服務,這些改動通常比限速規則更能提升整体抓取量。
怎么確認限速没有伤到抓取
在訪問日誌里按狀態碼和 UA 統計一段時間的分布,重点看两件事:
- 429 占该蜘蛛請求量的比例,是否長期高于一個很小的水平。
- 被限速的 URL 之後有没有重新被抓,間隔是否在拉長。
如果某個目錄的 429 比例一直很高,而且後續重试越来越少,說明限速范围開得太大,應该收窄到具体的慢路径上。
限速是手段而不是目的。让蜘蛛慢一点可以接受,让它誤以為站点坏了或者頁面消失了,代價要大得多。