做蜘蛛池入口页时,有一类问题经常被忽略:页面本身能打开,但目标链接是在“有会话”的情况下才渲染出来的。比如先 Set-Cookie 再跳转、必须带某个 Cookie 才输出链接,或者靠前端脚本先写 Cookie 再拉取列表。这类设计对人访问看不出问题,但对搜索蜘蛛来说,往往就是“页面是空的”。
搜索蜘蛛的请求基本是无状态的
主流搜索引擎的抓取程序在抓一个新 URL 时,通常不会携带你浏览器里的 Cookie。它更像一个干净的 HTTP 客户端:发一个 GET 请求,拿回响应,然后解析里面的链接。第一次访问时不会有你站点设置的会话 Cookie,也不会走你为老访客准备的“已经是会员”分支。
所以只要你的入口页把链接输出逻辑挂在“Cookie 存在”这个条件上,第一次抓取拿到的就是没有链接的那一版。搜索蜘蛛可能后续再访问,但如果每次都是全新会话,它就一直看不到那部分内容。
几种常见实现,分别会发生什么
- Set-Cookie 后 302 跳转:第一次请求返回 302 加 Cookie,跳转后的页面才有链接。搜索蜘蛛会跟随一次跳转,但第二次请求通常仍不带 Cookie,可能又回到 302,形成循环或停在中间页。
- session 判断后再输出:如果链接只在会话变量有值时才输出,搜索蜘蛛拿到的是空列表或“请先登录”的提示文字。
- 前端写 Cookie 再渲染:脚本执行需要时间,且搜索蜘蛛对 JS 的渲染能力有限,链接能否被发现取决于渲染队列,稳定性差。
- 按 UA / Referer / IP 做过滤:这类判断只要写错一个条件,就会把搜索蜘蛛的请求当成异常流量,直接返回空页或验证页。
怎么自己验证
不用等日志,直接用不带任何 Cookie 的请求测一遍最直观。命令行里请求入口页时故意不带 Cookie 参数,看返回的 HTML 里有没有目标链接:
curl -s -A "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" https://example.com/entry | grep -c "目标域名"
如果计数是 0,说明链接根本没出现在首次响应里。再换成不带 UA 的普通请求测一次,两次结果如果差别很大,就要检查是否存在 UA 判断。
需要访问控制时怎么折中
如果入口页确实不想被普通访客随便看,可以做分层,而不是把所有逻辑压在同一个条件上:
- 把入口页做成无状态页面,目标链接直接写在首次返回的 HTML 里,不依赖 Cookie 或会话。
- 需要限制的只是“人看到的样子”,可以用样式、跳转或前端交互处理,但别让链接本身消失。
- 如果使用 UA 白名单放行搜索蜘蛛,要同时校验真实来源 IP,避免被伪造 UA 的采集器蹭到,也不要只靠 UA 字符串做安全判断。
- 入口页不要放在需要 Basic Auth 或登录后才能访问的目录下,这类页面搜索蜘蛛一般拿不到内容。
小结
入口页的核心作用是让搜索蜘蛛顺着链接发现目标 URL,任何“先建立会话再给内容”的设计都在增加这一环节的不确定性。把链接放进首次响应、保持页面无状态,是更省心的做法。当然,发现并不等于收录,最终能不能进索引还要看目标页自身的内容质量,入口页只能解决“被发现”这一段。