不少人在入口页上线之后习惯性套一层 CDN 和安全防护,图的是稳定和抗压。但抓取量下降、日志变少、页面迟迟没有动静,问题常常不在页面本身,而在源站和蜘蛛之间的那一层中间服务。这一层做得好是缓冲,做得不好就是一道看不见的门。
CDN 对蜘蛛抓取的两面性
CDN 的默认目标是给真人用户加速,缓存策略以“尽快返回”为优先;而蜘蛛关心的是“拿到的是不是最新、最完整的版本”。两者目标不一致时,就会出现下面几种情况。
蜘蛛抓到的是缓存里的旧版本
如果入口页的缓存 TTL 设得很长,你更新了标题、内容或链接结构,蜘蛛第一次来仍然拿到旧 HTML。它不会报错,只是继续按旧版本理解这个页面。入口页本来就靠内容变化维持抓取兴趣,缓存时间过长等于把更新节奏掐掉了。
回源变少,源站日志看不到蜘蛛
缓存命中率高的时候,大量请求在边缘节点就被消化了,源站日志里几乎看不到蜘蛛的身影。这时候如果只看源站日志,很容易误判成“蜘蛛不来了”,实际上蜘蛛来了,只是没走到源站。判断抓取情况要把 CDN 侧的访问日志一起看。
节点分布与蜘蛛来源不匹配
蜘蛛的抓取出口和你选的加速区域不一定重合。加速区域只覆盖了部分地区的用户,蜘蛛可能从别的线路过来,走到的是没有优化的路径,首字节时间反而更长。
WAF 与安全策略的常见误伤
安全防护的默认规则是按“像不像正常用户”来判断,而蜘蛛的访问特征恰恰和爬虫很像——短时间内大量请求、固定 UA、不执行 JS、不带 Cookie。以下几类配置最容易误伤:
- 速率限制:入口页被集中抓取时触发限流,直接返回 429 或 403。
- UA 黑名单:批量拉黑爬虫类关键词时,把正规蜘蛛也一起挡了。
- JS 挑战与人机校验:蜘蛛不执行 JS,拿到的是一段空壳页面或校验页。
- 地区封禁:蜘蛛出口所在地区被封,请求直接被拒。
- Cookie 与指纹校验:没有会话记录的访问一律被判定为异常。
这些规则在防护真实攻击时是有效的,但用在入口页上,需要给已知蜘蛛留出明确的放行规则,而不是靠调低整体阈值来“顺便”放行。
出问题时先查哪一层
排查顺序建议从最靠近源站的地方往外推,避免一上来就改页面:
- 直连源站测试:用临时域名或本地 hosts 指向源站 IP,确认源站本身能正常返回 200 和完整 HTML。
- 对比带 CDN 的结果:同一 URL 分别走源站和走 CDN,看状态码、响应体长度、响应头是否一致。
- 看响应头:X-Cache、CF-Cache-Status、Age、Server 等字段能看出是命中缓存、回源,还是被防护层拦下。
- 看两侧日志:CDN 日志和源站日志对照,确认请求到了哪一层、被谁拦下。
- 检查被缓存的文件:robots.txt、sitemap、入口页 HTML 是否被长时间缓存,导致蜘蛛读到过期内容。
配置上的几条实用建议
- 给已知蜘蛛的 UA 和 IP 段设置显式放行,优先级高于通用限流规则。
- 入口页 HTML 的缓存 TTL 设短一些,静态资源可以长,两者分开配置。
- 关闭作用在入口页上的 JS 挑战和验证码,防护重点放在后台和管理路径。
- 保留真实访客 IP 的日志字段,否则日志里全是 CDN 节点 IP,没法区分蜘蛛和普通请求。
- 留一条不经过 CDN 的直连通道,方便快速判断问题到底出在哪一层。
- 如果安全产品会把请求转发到拦截页,确认那个拦截页返回的状态码不是 200。
CDN 和 WAF 本身不是问题,问题在于默认配置是给真人流量设计的,而蜘蛛的访问方式和真人差得很远。要么在规则里给蜘蛛单独开一条路,要么接受抓取量被削掉一部分。
最后提醒一点:入口页数量多、域名杂,很容易触发共享的防护阈值,出现“一个入口页被限流,整批入口页跟着受影响”的连锁反应。给蜘蛛池单独划一个防护策略或独立域名分组,比事后一个个排查要省力得多。