做蜘蛛池或入口页运营时,经常会遇到一种尴尬情况:明明在入口页里加了新的目标链接,日志里却迟迟看不到搜索蜘蛛来抓。排查半天,服务器正常、页面能打开、链接也没写错——这时候要找的方向可能不是“页面能不能访问”,而是“搜索蜘蛛到底有没有拿到最新版本的内容”。
304 和 CDN 缓存是两件事
304 Not Modified 是源站对条件请求的回应。搜索蜘蛛再次抓取同一个 URL 时,通常会在请求头里带上 If-Modified-Since 或 If-None-Match,相当于问一句“这个页面从上次抓取之后变过吗”。如果服务器判断没变,就回 304,蜘蛛沿用上一次抓到的内容,不再重新下载。
CDN 缓存则发生在更前面一层。请求还没到源站,边缘节点就把自己存的那份副本直接返回了。这时候蜘蛛拿到的可能是几小时甚至几天前的 HTML。
两者共同的结果是:蜘蛛看到的不是你现在这份页面,里面新加的链接自然也不会被发现。
返回 304 时,搜索蜘蛛看到的是什么
正常配置下,304 是省流量的好做法。问题出在配置出错:有人为了“加快响应”,把入口页写死成永远返回 304,或者 Last-Modified 不随内容更新而变化。这种情况下,即使你改了入口页,蜘蛛问“变了吗”,服务器答“没变”,新链接就一直躺在源站里没人看。
还有更隐蔽的情况:动态生成的入口页没有输出正确的 Last-Modified,或者反向代理把 ETag 设成了一个固定值。表面上页面能打开、内容也对,但对搜索蜘蛛来说它始终处于“未更新”状态。
CDN 缓存会让新链接延迟上线
入口页如果挂在 CDN 后面,默认 TTL 常常是几十分钟到几小时,长的按天算。源站一改,边缘节点并不会立刻同步。
- 蜘蛛第一次抓取,拿到缓存版本 A,里面还没有新链接;
- TTL 到期前再次抓取,返回的仍然是 A;
- 直到缓存过期或被主动刷新,才有机会拿到新版本 B。
如果入口页是唯一的新 URL 来源,这段时间就是纯粹的发现延迟。你以为的“蜘蛛不抓新链接”,其实是它还没看见。
怎么确认自己遇到的是哪一种
- 用 curl -I 直接请求入口页,看返回状态码是 200 还是 304,以及 Last-Modified、ETag、Age、X-Cache 这类响应头;
- 带上 If-Modified-Since 再请求一次,看源站是否会错误地一直回 304;
- 拿源站 IP 直连抓一次,再走 CDN 域名抓一次做对比,看内容是否一致;
- 在服务器日志里找搜索蜘蛛的请求,看同一 URL 的返回码分布,是不是长期只有 304 或只有缓存命中。
更新入口页时的几个稳妥做法
- 更新内容后主动刷新 CDN 缓存,尤其入口页这类承担 URL 发现职责的页面;
- 检查 Last-Modified 是否随内容变化,避免服务器无差别返回 304;
- 不要为了绕开缓存,每次更新都换一个新 URL。入口页地址频繁变动,等于丢掉之前积累的抓取记录,还容易产生一批重复页面;
- 如果入口页改动很频繁,可以适当降低节奏,把新增链接攒到一次更新里,减少“频繁变动但无实质变化”的情况;
- 给新链接留出观察时间。缓存过期加上蜘蛛重新抓取,本来就不是即时过程。
入口页能不能被重新解析,取决于搜索蜘蛛是否真的下载到了最新版本。缓存和错误的 304,都会让“已经更新过了”停留在源站上。
最后提醒一句:入口页的作用是让 URL 被看见,不是保证被收录。即使链接被重新解析到,后续能否抓取和收录,仍然取决于目标页自身的状态。把缓存和状态码这一层排查清楚,至少能排除掉一部分“明明改了却没动静”的疑惑。