抓取诊断时,大部分人先看狀態碼:200 就放心,404 就去修,5xx 就去查服務器。但蜘蛛在一次請求里拿到的不只是一個數字,還有一整组响應头。這些头信息决定了它怎么解析内容、要不要重新下载、下一次什么时候再来。狀態碼正确、响應头寫错,同样會让抓取结果打折扣。
Content-Type 與字符集:决定蜘蛛怎么讀這段内容
响應头里的類型声明,是蜘蛛判断「這是不是一篇網頁」的第一依據。
- charset 缺失或與頁面声明不一致:HTML 里寫 UTF-8,响應头寫別的编碼,蜘蛛按响應头解析,正文可能變成乱碼,影响内容提取。
- 類型寫成 application/octet-stream 或 text/plain:頁面路径返回下载類型,蜘蛛可能当成文件處理,而不是当作可解析的 HTML 頁面。
- 接口返回 JSON 却挂在可索引路径下:内容本来不是给用戶看的頁面,却占用了抓取配額。
這几類問题的共同点是:用戶在浏览器里看不出異常,因為浏览器容错强;而蜘蛛按声明解析,出错就直接体現在正文质量上。
压缩與传輸方式:体积小不等于传輸完整
支持 gzip 或 brotli 能让同样的 HTML 少传不少字节,對蜘蛛和用戶都是好事。需要注意的是压缩之後不能出現截断,传輸中途断開會让蜘蛛拿到不完整的文档。用分块传輸、没有 Content-Length 通常没有問题,但如果前面的代理對分块處理出错,蜘蛛也可能讀到残缺内容。日誌里同一 URL 反复抓取、單次抓取体积明顯偏小,就值得往這個方向查。
缓存相關的头:让回訪更省,但別让更新迟到
ETag 和 Last-Modified 的作用是让蜘蛛回訪时能带上校驗條件询問,内容没變就返回 304,省掉一次完整下载。這對抓取预算是正向的。但要注意,304 只表示「内容没變」,並不代表蜘蛛會因此調整已有索引;反過来,如果頁面更新後缓存标记没有跟着變化,蜘蛛可能一直收到 304,始终看不到新内容。
另一個方向是给 HTML 設定很長的 Cache-Control: max-age 或 immutable。用戶端可能被 CDN 缓存住,蜘蛛回訪时也拿到舊版本,更新被推迟。静態资源适合長期缓存,頁面本身通常不适合。
Location:跳轉鏈要收敛到落地頁
Location 是另一處容易出問题的地方。單次跳轉属于正常的路径調整,但跳轉鏈太長时,每次抓取都要多花几次請求,還容易在中途丢失參數。更稳妥的做法是让所有變体都直接指向最终落地頁,而不是 A 跳到 B、B 再跳到 C。
X-Robots-Tag:藏在头里的索引指令
有些站点不方便改 HTML,就用响應头里的 X-Robots-Tag 控制索引狀態。它确實有效,但也容易被忽略:某個中間层、CDN 規則或歷史配置给整站加上了這個字段,頁面却照常返回 200,從表面看一切正常。排查「抓取正常但迟迟没有進入索引」這類情况时,值得专门看一眼响應头里有没有這個字段。
Retry-After:過载时的礼貌,不是常規限流手段
服務器压力大时返回 503 並带上 Retry-After,比直接连接超时更友好,等于告诉蜘蛛多久之後再来。但不要長期拿它当挡箭牌:持續返回 503 會打乱抓取节奏,恢复之後也需要一段時間才能回到原来的訪問频率。
Vary 與 Set-Cookie:缓存层面的连带影响
Vary: User-Agent 的含义是不同 UA 给不同版本。如果 CDN 真的按 UA 分版本缓存,蜘蛛拿到的可能是移動版或精简版 HTML,與你想让它抓的版本不一致。另外,静態资源上带着 Set-Cookie,會降低缓存命中效率,這類配置遗留同样會影响抓取时的响應表現。
一份可以照着走的排查清單
- 用抓取工具查看响應头,確認 Content-Type 與 charset 和實际内容一致。
- 检查是否誤挂了 X-Robots-Tag,尤其留意全站級別與中間层配置。
- 確認压缩传輸没有截断,對比同一 URL 多次抓取的体积是否稳定。
- 看跳轉鏈長度,把多跳收敛成一跳直達落地頁。
- 確認 HTML 的缓存策略不會让它長期返回 304 舊版本。
- 503 與 Retry-After 只在真實過载时使用,不当作日常限流開關。
狀態碼告诉你「這次請求成没成」,响應头告诉你「蜘蛛讀到了什么、下次還會不會来」。两者一起看,抓取問题才容易定位到具体的那一层配置。