蜘蛛抓取一個 URL 时,最先拿到的並不是正文,而是服務器返回的响應头。這部分内容在浏览器里看不见,很多维護入口頁的人只盯着标题、正文和連結,等到抓取異常时反而查不出原因。响應头本身不保證任何收錄结果,但它决定了蜘蛛這次請求是繼續解析、稍後再来,還是干脆放弃。
狀態碼是第一道判断
狀態碼决定蜘蛛要不要繼續處理這個 URL。200 是正常,301 表示永久迁移,302 和 307 属于临时跳轉,404 和 410 表示资源不存在,403 是拒绝訪問,429 和 503 通常代表压力過大或临时不可用。對入口頁来说,關键不是返回哪個碼,而是同一個 URL 長期返回的碼是否稳定。今天 200、明天 403、後天跳 302,蜘蛛很难判断這個頁面的真實狀態,抓取频次往往會下降。
如果确實需要限流,用 503 並配合 Retry-After 头,比直接返回 200 的错誤頁更清晰。反過来,把错誤頁面伪装成 200,會让蜘蛛把無效内容当成正常頁面處理,長期看是负面的。
缓存與更新信号:Last-Modified、ETag、Cache-Control
這几個字段帮助蜘蛛判断頁面有没有變化,從而减少無效抓取。Last-Modified 應该反映内容的真實更新時間,而不是每次請求都刷新成目前時間。有些程序在動態渲染时會顺手寫入目前時間,结果每次訪問都被認為内容更新了,蜘蛛的抓取需求被反复触發,抓取预算被消耗在入口頁上。
ETag 的作用類似,如果服務器每次生成的 ETag 都不一样,蜘蛛同样無法判断内容是否稳定。Cache-Control 里常见的 no-store 會让中間层無法缓存,增加源站压力;對入口頁一般建议允许較短的缓存時間,减少重复請求。這些字段不直接决定抓取结果,但會影响抓取的节奏和频率。
内容類型與压缩:Content-Type、charset、Content-Encoding
Content-Type 缺失或者寫错,蜘蛛可能把 HTML 当成纯文本處理,頁面结构無法被正确解析。charset 要和頁面内的 meta 声明保持一致,UTF-8 是最省事的選擇。编碼声明冲突时,容易出現标题乱碼、正文被截断的現象,這類問题在日誌里通常表現為抓取正常但頁面内容異常。
Content-Encoding 用于声明 gzip 或 br 压缩。压缩本身有利于传輸,但如果压缩後的内容不完整,蜘蛛拿到的可能只是半截文档,解析自然失敗。開啟压缩後建议實际抓取一次,確認返回内容是完整的。
机器人相關字段:X-Robots-Tag
X-Robots-Tag 是响應头形式的机器人指令,作用類似頁面里的 meta robots,但可以按目錄、按文件類型批量下發,也能覆盖到非 HTML 资源。它的風險在于配置范围太大:如果运维在全局层面加了 noindex 或 nofollow,入口頁可能在不知情的情况下被整体限制,而頁面本身看不出任何異常。
排查时可以把 robots.txt、meta robots 和 X-Robots-Tag 三處對照一遍,確認入口頁确實是開放抓取的狀態。三者不一致时,通常以更嚴格的指令為准。
容易被忽略的几個坑
- 全站错誤頁统一返回 200,蜘蛛把错誤頁当正常頁面處理。
- 跳轉鏈路過長,中間夹着多次 302,抓取效率下降。
- Last-Modified 每次請求都變化,蜘蛛反复回抓。
- 源站和 CDN 返回的响應头不一致,中間层覆盖了原始設定。
- WAF 或防護层對部分 UA 返回 403,而日誌里只看到少量請求。
- 限流时直接断開连接,没有返回 429 或 503,蜘蛛只能判定為失敗。
- X-Robots-Tag 被全局配置誤加,入口頁被静默限制。
一條可执行的排查路径
- 用 curl -I 或浏览器的網絡面板,直接查看入口頁的响應头。
- 對比直连源站和经過 CDN、防護层之後的结果,確認头部字段有没有被改寫。
- 抽查一批入口頁,看狀態碼、Last-Modified、Content-Type 是否存在共性異常。
- 结合訪問日誌,观察狀態碼分布和抓取频次的變化趋势。
- 發現問题後分批修改配置,避免一次性改動導致整体波動。
响應头不是提升抓取的手段,而是排除干扰的基础。先把狀態碼、缓存和内容類型這三類字段保持稳定一致,再谈入口頁的數量和结构,通常更省事。