蜘蛛抓一個 URL 时,拿到的並不是一整块頁面,而是先收到响應头,再收到正文。很多站長只盯着 HTML 里的 title、meta 和正文,忽略了头部那几行字段,结果頁面没被抓走却找不到原因。响應头决定了蜘蛛怎么判断“這是什么東西、要不要繼續讀、按什么编碼讀”,值得單獨检查一遍。
第一眼:狀態行與 Content-Type
Content-Type 告诉蜘蛛返回的是 HTML、XML、图片還是文件流。如果動態接口把 HTML 頁面标成 text/plain 或 application/octet-stream,蜘蛛可能只当成一個文件下载,不去解析里面的連結,URL 發現就在這里断掉。
反過来也不合适:把图片、PDF 誤标成 text/html,蜘蛛會按頁面處理,抓到一個几乎没有可用内容的“頁面”。
- 頁面型 URL 返回 text/html; charset=utf-8
- XML 站点地图返回 application/xml 或 text/xml
- 图片、视频、文档返回各自對應的類型
检查方法很简單:用 curl -I 看目标 URL 的 Content-Type 那一行。模板頁較多时,可以寫脚本按頁面類型批量抽查。
编碼声明不一致會带来什么
头部 charset 與 HTML 里 meta charset 不一致时,蜘蛛通常按头部優先解碼,中文可能變成乱碼,标题、摘要、锚文本一起受影响。建议全站统一 UTF-8,並在头部明确声明。
個別頁面如果用了非 UTF-8 编碼,容易出現問号或方块,蜘蛛讀到的文本與用戶看到的並不一致。
X-Robots-Tag:藏在头部里的 robots 指令
這是 HTTP 头版本的 meta robots,寫在响應头里生效。它主要解决那些没法在 HTML 里寫 meta 的文件,比如 PDF、图片、视频。
常见寫法:
- X-Robots-Tag: noindex —— 不影响抓取,但不让進入索引
- X-Robots-Tag: noindex, nofollow
- X-Robots-Tag: googlebot: noindex —— 只對特定蜘蛛生效
容易踩的坑有三個:CDN、反向代理或框架中間件统一给所有响應加上了 noindex,上线後不易察觉;測試环境打開的限制忘了關,跟着配置一起進生产;只改了 HTML 里的 meta,没检查头部還在下發同样的指令。
头部指令通常優先級高于 meta:两邊冲突时,更嚴格的那個生效。所以在头部加了 noindex,再去 HTML 里删 meta 是没有用的。
還要注意與 robots.txt 的先後顺序:如果 robots.txt 禁止抓取,蜘蛛根本看不到响應头,也就看不到 noindex。想让頁面從索引中登出,一般先允许抓取,再给 noindex。
Vary 與缓存:同一 URL 的不同版本
Vary 告诉缓存“這個响應取决于哪些請求头”。Vary: User-Agent 會让缓存把不同 UA 的請求分開存放,對蜘蛛来说,它拿到的版本可能和普通用戶不同。
如果站点按 UA 给蜘蛛返回不一样的内容,属于典型的伪装,風險很高,不建议使用。确有区分需求时,可以用 Vary: Accept-Encoding 這類與内容编碼相關的字段。
Vary: * 會让缓存几乎失效,源站压力上升,間接拖慢蜘蛛的抓取节奏,属于常见但容易被忽略的性能坑。
内容编碼與長度
Content-Encoding: gzip 或 br,能让蜘蛛用更少的带宽拿到同样的正文,列表頁這類结构重复的頁面收益更明顯。压缩通常由服務器或 CDN 自動完成,但要確認 HTML 响應没有被跳過。
Content-Length 只是声明,不是必须;分块传輸也能被正常解析,不必為它纠结。
一份可落地的检查清單
- 用 curl -I 抽查首頁、栏目頁、詳情頁、Sitemap 和图片的响應头
- 確認 Content-Type 與 charset 正确、全站统一
- 搜尋全站配置里的 noindex,確認只有目标 URL 命中 X-Robots-Tag
- 检查 Vary 是否被滥用,尤其是 Vary: *
- 在日誌里對照蜘蛛拿到的狀態碼與响應大小,看有没有“200 但内容異常”的情况
头部只有几行,却决定了蜘蛛後面的所有動作。把這几行检查清楚,再去看内鏈、Sitemap 和抓取预算,排查顺序會顺很多。