做蜘蛛池入口頁时,很多人把注意力放在 URL 结构、内鏈和响應時間上,却忽略了一個很小的變量:Cookie 和會话狀態。它平时不顯眼,但一旦入口頁依赖會话才能輸出内容,蜘蛛拿到的頁面可能和一個普通訪客完全不是同一個。
蜘蛛的請求通常是無狀態的
搜尋引擎蜘蛛發起請求时,一般不會像浏览器那样儲存並回传上一次的 Cookie,多數情况下每次抓取都是一次全新的、不带 Cookie 的請求。這意味着,任何“必须先有 Cookie 才给内容”的逻辑,都可能把蜘蛛挡在门外,或者让它只看到一個空壳頁面。
常见的依赖會话的场景包括:
- 首次訪問就强制跳轉到带 jsessionid、PHPSESSID 之類參數的地址;
- 用 Cookie 记錄“已同意隐私條款”之後才展示正文;
- 用 Cookie 做 A/B 分流,蜘蛛每次被分到不同版本;
- 用 Cookie 判断来源地区、語言或渠道,再决定返回什么内容。
三種最容易踩的坑
一、會话參數寫進 URL
当服務端用 URL 重寫把會话 ID 寫進地址,蜘蛛抓到的連結就會带着一長串會话參數。這類地址對每個新會话都可能不同,容易造成同一内容被反复發現、重复抓取,也會稀释入口頁本身的權重。建议在入口頁關閉 URL 重寫,實在關不掉,就用 canonical 做归一。
二、同意墙挡在正文前面
Cookie 同意彈窗如果實現成“内容必须由 JavaScript 在用戶確認後才渲染”,蜘蛛往往只能看到提示文字。更稳妥的做法是把正文直接放在 HTML 里,彈窗只做视觉遮挡;确需交互时,也让未携带 Cookie 的首次請求返回完整内容。
三、缓存被會话狀態废掉
一旦响應头里出現 Cache-Control: private,或者頁面因為 Set-Cookie 而被 CDN 判定為個性化内容,邊缘缓存的命中率就會下降。對蜘蛛来说抓取成本没變,但你服務器承受的並發會明顯上升,响應時間也更容易抖動。
Set-Cookie 本身要不要紧
單纯返回 Set-Cookie 头,一般不會直接導致抓取失敗,蜘蛛通常會忽略它。真正的問题在于這個 Cookie 是否反過来决定了後面的响應:如果入口頁對每個無 Cookie 請求都返回相同内容,影响不大;如果無 Cookie 就跳轉、就空白、就返回 403,那就属于典型的“抓取通道被會话逻辑掐断”。
判断标准很简單:用不带 Cookie 的請求訪問一次入口頁,看看拿到的 HTML 和你自己在浏览器里看到的是不是同一份。
落地时的几條建议
- 入口頁保持無狀態:正文、标题、内鏈都不依赖任何會话變量。
- 把识別判断放在 UA 與 IP 上:需要区分蜘蛛时,優先用反向解析驗證過的来源 IP,而不是靠 Cookie。
- 會话參數不進連結:避免把會话 ID 寫進 href;歷史上已产生的,做跳轉或 canonical 归一。
- 分流留一份預設版本:A/B 測試對蜘蛛固定返回主版本,避免同一入口頁反复改内容。
- 把缓存策略寫清楚:入口頁尽量走公共缓存,减少動態逻辑带来的响應波動。
怎么驗證有没有問题
三個低成本動作就够用:一是用命令行工具或抓取工具發起不带 Cookie 的請求,對比返回内容;二是看响應头里的 Set-Cookie、Cache-Control、Vary 字段是否出現在入口頁上,尤其留意 Vary: Cookie;三是在服務器日誌里筛出蜘蛛請求,看狀態碼分布是否和预期一致,有没有大量跳轉或 403。
會话狀態属于那種“平时不出声、出事就成片”的配置。把入口頁做成無狀態可讀的頁面,往往比事後排查抓取異常省事得多。