蜘蛛池知识

蜘蛛池入口页的 Cookie 与登录态:蜘蛛拿不到的那部分链接

蜘蛛访问入口页时通常不带 cookie、不带登录态、也不保留本地存储。如果链接依赖这些状态才出现,日志里看着抓取正常,实际能跟下去的链接却很少。本文梳理几种常见的“藏链接”写法,给出一套用无状态请求对比源码的排查方法,以及把链接放回服务端直出 HTML 的调整思路。

蜘蛛池知识

蜘蛛池入口页的 Cookie 与登录态:蜘蛛拿不到的那部分链接

做蜘蛛池的人常碰到一种情况:日志里蜘蛛来的次数不少,入口页也返回 200,但真正被跟下去的链接寥寥无几。查了半天服务、DNS、robots 都没问题,最后发现原因在“链接需要一点状态才显示”——比如要先落一个 cookie、先过一层会话校验,或者等页面上某个脚本执行完。而蜘蛛第一次来的时候,这些东西往往都不具备。

蜘蛛访问入口页时,默认不带什么

  • 不带你的业务 cookie,也不带上次访问留下的任何会话标识
  • 不带登录态,除非这个链接本身就是公开可访问的
  • 不执行“需要点击才触发”的交互
  • 通常不保留本地存储里的内容
  • 同一个 IP 段内的多次请求,未必共享你期望的会话

换句话说,所有“靠浏览器状态才成立”的链接,对蜘蛛来说都不成立。这不是抓取方偷懒,而是它的访问方式本来就是这样。

常见的几种“藏链接”写法

1. 登录或授权后才展示

把入口页的关键链接放在登录后才能看到的位置。对用户是合理的,对蜘蛛等于不存在。有的站点让友情链接或目录链接按来源展示,也会踩到同样的问题。

2. Cookie 弹窗或同意条之后才渲染

入口页先盖一层遮罩,用户点“同意”之后主体内容才出现。如果主体链接是点击后才注入到页面里的,蜘蛛第一次拿到的 HTML 就是空的。

3. 服务端按 session 判断

服务端先下发 set-cookie,再用这个 cookie 判断来源、拼接链接列表。蜘蛛每次都是新会话,拿到的可能是空列表,或者一份简化的默认列表。

4. JS 动态注入链接

用 fetch 拉一个 JSON 再拼到页面上。这种写法对能执行 JS 的渲染型抓取有一定机会,但脚本延迟、超时、报错都会让链接拿不到,不同抓取方对 JS 的执行程度也不一样,不适合当作稳定路径。

5. 按 Referer 判断

只有带特定来源页的请求才返回链接。蜘蛛直接访问 URL,通常没有你期望的 Referer,于是看到的是一个简化页面。

怎么确认是不是这个问题

  1. 用 curl 或同类工具直接请求入口页,不带任何额外状态,把返回的 HTML 存下来
  2. 在返回内容里搜目标链接的关键词,确认它出现在源码里,而不是只出现在浏览器开发者工具的元素面板里
  3. 关掉可能干扰的浏览器插件,禁用 JS 再打开同一个 URL,对比两次结果
  4. 对比带 cookie 和不带 cookie 的两次响应,差异部分基本就是蜘蛛看不到的部分
  5. 看日志里蜘蛛请求入口页时的响应体大小,如果明显小于正常用户看到的,通常就是这里的原因

调整思路:把该给蜘蛛的链接放到服务端直出

  • 入口页的主体链接列表在服务端渲染好,直接写进 HTML 源码
  • Cookie 和登录态只服务于用户侧功能,比如个人中心,不要用它来决定链接是否出现
  • 遮罩、弹窗、同意条尽量只做视觉层,不改动主体 HTML
  • 确实需要 JS 的地方,可以考虑预渲染或服务端渲染,但要接受它存在延迟和失败率
  • 分页、列表、归档这类抓取路径,优先做成静态可访问的 URL

一个容易忽略的点

有些程序在缺少 cookie 时会返回一个“欢迎页”或跳转页,状态码仍然是 200。这种软性拦截在日志里看不出来,只能靠对比源码发现。建议在改动入口页模板之后,固定做一次无状态请求的回归检查,把它当成上线流程的一部分。

链接能不能被跟下去,先看它有没有出现在不带任何状态的 HTML 里。这一条比任何优化技巧都优先。