结论先放在前面
搜尋蜘蛛的抓取基本是無狀態的:它預設不携带你的 Cookie,不會走登入流程,也不會像浏览器那样维持一個會话。所以当入口頁的連結依赖“先種 Cookie 再渲染”或“登入後才顯示”时,蜘蛛拿到的往往是一個空壳頁,自然也就走不到後面的目标 URL。
這不是蜘蛛“能力不行”,而是设計上就不该用它去模拟用戶登入。把要被抓的入口頁做成無需會话即可讀取,才是更稳的做法。
為什么蜘蛛看不到登入後的内容
- 不带 Cookie:蜘蛛請求通常是干净的,你上一次訪問留下的會话對它無效。
- 不走登入表單:提交帳號密碼、驗證碼、短信校驗這類流程,蜘蛛不會执行。
- 會话寫在 URL 里更糟:形如 ?sid=xxxx 的入口地址既不稳定,也容易在換會话後失效。
- 渲染队列有时延:如果連結是 JS 讀取 localStorage 或 Cookie 後再插入的,即使進了渲染流程,也可能因為取不到值而渲染出空内容。
怎么驗證自己是不是踩了這個坑
- 用不带 Cookie 的命令行請求抓一次入口頁,看返回的 HTML 源碼里有没有目标連結。
- 開浏览器隐身窗口直接訪問入口頁,不登入、不点任何按钮,對比“正常訪問”时的差异。
- 用搜尋平台自带的抓取測試 / URL 检查類工具,看它渲染出来的结果與你的预期是否一致。
- 翻服務器日誌,按蜘蛛 UA 過滤,观察狀態碼與响應体大小。响應体常年只有几百字节、且明顯小于正常頁面,基本可以確認是空壳頁。
几種“半遮半掩”的常见寫法
1. 首次訪問下發 Cookie,第二次才輸出連結
有些入口頁會先 Set-Cookie,再在後續請求里判断 Cookie 是否存在来决定是否輸出連結。對蜘蛛来说,每次請求都像“第一次”,于是永遠停在無連結的那一版。
2. 前端判断後再插入連結
連結由 JS 在客戶端注入,注入前提是本地存在某個标记。這種情况服務端返回的源碼里没有連結,能否被發現完全取决于渲染行為,稳定性很差。
3. 入口頁直接 302 到登入頁
蜘蛛跟随跳轉後落在一個登入頁上,入口頁的作用等于零,還可能让整條跳轉鏈被判定為無效路径。
可落地的調整思路
- 把需要被抓取的入口頁單獨拆出来,放在不做鉴權的路径下,内容用服務端渲染,連結直接寫在 HTML 里。
- 入口頁只承担“列出目标連結”的职责,用戶登入区、會員区與入口頁彻底分离。
- 尽量避免让入口頁依赖任何 Cookie 才能輸出正文,包括“地区判断”“AB 測試分流”這類看似無害的逻辑。
- 如果确實需要動態輸出,至少保證首屏 HTML 里就有連結,而不是等脚本执行完才出現。
- 定期用無 Cookie 的方式做一次回归检查,把“入口頁是否還能被裸抓”纳入日常巡检。
不要用 User-Agent 判断给蜘蛛返回和普通用戶不一样的内容。這類做法属于典型的伪装,風險遠大于收益,也解决不了“連結本来就不该公開”的問题。
顺带说一句 Cookie 與缓存
入口頁如果频繁下發 Set-Cookie,CDN 或缓存层往往會因此選擇不缓存,结果是每個蜘蛛請求都直接打到源站。抓取量稍微上来一点,源站压力和响應時間都會明顯變化,進而又影响抓取节奏。能不用會话就別用,對抓取和對服務器都更省事。
小结
判断标准其實很简單:把 Cookie 清空、不登入去訪問入口頁,如果目标連結還在,蜘蛛大概也能看到;如果不在了,蜘蛛看到的和空頁面差不多。蜘蛛池的價值在于让 URL 更容易被持續發現,而不是给蜘蛛設定一道它永遠過不去的门槛。