入口頁寫好了,代碼里也没有任何屏蔽寫法,但服務器日誌里几乎看不到搜尋蜘蛛的訪問记錄,目标 URL 也迟迟没有被發現。這種情况問题往往不在 HTML,而在請求還没抵達入口頁之前就被拦下了。
被拦截时,搜尋蜘蛛實际會看到什么
防火墙、CDN 安全模块或主机自带的安全插件,通常在請求到達應用层之前就做出判断。對抓取而言,结果大致分三類:
- 直接拒绝:返回 403、406 或 503,蜘蛛這次抓取失敗,可能稍後重试,也可能把入口頁标记為暂时不可用。
- 软拦截:返回狀態碼 200,但頁面内容是驗證頁、跳轉頁或一段空壳 HTML。蜘蛛拿到了响應,却没有拿到任何連結。
- 排队或降速:返回 429,或者把請求放進慢速通道,抓取频率被压得很低,發現目标 URL 的時間被拉長。
第三種情况最容易被忽略,因為狀態碼看起来不算嚴重,但在日誌里會表現為蜘蛛来過一两次之後就再也不出現。
几種容易被忽略的拦截形式
整站級的 WAF 規則
有些規則是為了防刷和防采集,命中條件可能是請求频率、請求头缺失、訪問路径特征,甚至 IP 所属的机房号段。蜘蛛從固定 IP 段發起請求,反而容易撞上這類規則。入口頁如果只是一堆連結、没有正文,還可能命中“疑似采集頁面”的規則。
JavaScript 挑战與驗證碼
這類拦截返回的也是 200,内容是一個需要执行脚本或点击驗證的頁面。搜尋蜘蛛基本不會去完成驗證,于是它拿到的就是一個没有連結的頁面。判断方法很简單:用不带 Cookie、不执行 JS 的方式請求入口頁,看返回的 HTML 里到底有没有目标連結。
速率限制
如果同一台服務器上放了很多入口頁,或者入口頁在短時間内被大量訪問,速率限制很容易被触發。触發之後不一定立刻返回错誤,有时只是把後續請求延迟處理,表現就是抓取断断續續。
怎么確認是拦截,而不是蜘蛛根本没来
- 在服務器日誌或 CDN 日誌里按搜尋引擎的 User-Agent 過滤,先看有没有记錄。完全没有记錄,說明請求在更前面就被丢弃了。
- 看响應碼分布。大量 403、429、503,基本可以鎖定是拦截。
- 用命令行模拟一次請求,對比带與不带常见蜘蛛 UA 的返回结果。如果两者返回内容不同,說明存在基于 UA 的分流。
- 检查 robots.txt 本身是否也被拦截。如果连它都返回 403,蜘蛛可能连抓取范围都讀不到。
- 看安全插件或 WAF 的控制台日誌,確認命中的是哪條規則,而不是凭猜测調整。
放行时要注意的邊界
確認真的是誤拦之後,處理方式通常是给已知的搜尋引擎 IP 段或驗證過的 UA 加白名單、單獨给入口頁路径降低拦截等級、關閉 JS 挑战、放宽速率限制。這里有几個容易踩的坑:
- 只靠 User-Agent 白名單並不安全,UA 可以伪造,更稳妥的做法是 IP 段與反向解析结合驗證。
- 不要為了放行而整站關閉安全模块,其他路径可能正在依赖這些規則。
- 放行後不要立刻下结论,蜘蛛重新抓取需要時間,观察一到两周的日誌趋势更可靠。
- 拦截解除不等于連結一定被發現。入口頁還需要能被正常解析、連結确實存在于 HTML 中,並且没有其他屏蔽手段叠加。
排查顺序建议從“請求有没有到達”開始,而不是從 HTML 寫法開始。很多所谓的連結不被發現,其實是响應根本没让蜘蛛讀到内容。
把拦截問题解决之後,入口頁只负责让目标 URL 進入待抓取队列,什么时候真正被抓取、抓取之後如何處理,仍然取决于目标頁本身的可訪問性和内容质量。這部分没有捷径,只能靠持續观察日誌来判断。