# v2.11.064 · 文章 URL 规范化 + 抓取观测盲区清零
> 这一版围绕「蜘蛛来了,但抓了不收录 / 收录不了也看不出为什么」。
> 主角是一个隐藏很久的 URL 规范化缺陷 —— 实测每域名 18.99 万条 URL 里 92% 中招。
> 其余五项都在补观测:让「抓取量到底花在哪」「谁改了配置」「源站是不是在拒连」变得可查。
🎯 92% 的 sitemap URL 被 Google 判为「非规范副本」
同一篇文章,系统里原先有 7 个地方各自生成 URL,而且各传各的随机盐:
| 生产者 | 用的盐 |
|---|---|
| sitemap | 蜘蛛家族盐 17 / 101 / 43 / 71 |
| 页面 canonical 标签 | 文章 ID |
| GSC 推送 | 17 |
| 百度推送 | 101 |
| 站内互链 | 渲染上下文 seed |
| 404 推荐 | 0 |
结果是同一篇文章有好几个不同的 URL,而只有 canonical 那一个是自指的。
sitemap 挂出去的全是非规范副本 —— Google 抓到后判定「替代网页(含适当的规范标记)」,
抓了但不索引。这正是「蜘蛛量不低、收录却上不去」的直接原因。
修复:新增唯一入口 ArticleURLPathCanonical / ArticleURLCanonical,
URL 只由文章自身决定(文章 ID + 它自己的栏目),不再受渲染上下文影响,七个生产者全部改走这里。
顺带修掉三个同源问题:
- ▸合并两份重复的 URL 渲染实现。 两份的日期种子不同,
{cid} 一个填真实栏目 ID、一个填空;
用 {cid}+{aid} 规则的站点,两边算出来是完全不同的路径,不只差一个月份。
- ▸同一篇文章出现在不同栏目的列表页里,原先会拿到不同 URL。 现在一律用文章自己的栏目。
- ▸GSC / 百度推送原先完全绕过域名 URL 规则,推出去的 URL 跟站点实际 URL 对不上,
白烧 Indexing API 配额。
📊 蜘蛛日志补上状态码与路由类型
spider.logs 此前只记「谁来了、访问了什么路径」,不记响应结果。
于是「1000 万次抓取」这个数字里,有多少是真实内容页、多少是跳转空转、多少是 5xx 报错,
在任何统计里都分不出来。
本版新增两列:
- ▸
status —— HTTP 状态码。302 灌水、503 降级、5xx 故障从此可分。 - ▸
route_kind —— 路由类型(内容页 / robots / sitemap / 跳转 / 缓存命中)。
> 实测意义:高抓取量时段里 robots.txt 稳定占全部请求的 41%~58%。
> 这在泛域名场景下是正常的(每发现一个新子域就要取一次 robots),
> 但在补上这两列之前,它和真实内容抓取混在同一个数字里,无法区分。
表结构变更为幂等加列,升级时自动执行,不影响历史数据。
🔀 修模式隔离:蜘蛛池的全局设置会串到站群
同一台机器上混跑多种模式时,有三处代码在读全局运营模式,而不是域名所在分组的模式。
后果是:给蜘蛛池调的设置,会影响到站群/单站域名的 sitemap 顶层信号和渲染策略。
三处已全部改为按分组解析。另加了一条源码审计测试——
今后谁再在这个包里直接读全局 operation_mode,测试会直接失败。
⏱ sitemap 缓存策略:摘掉一个压抓取频率的响应头
原先三处各说各话:内部缓存 10 分钟 / 5 分钟(写死),命中时回 max-age=300,
未命中时回 max-age=3600。同一个 URL 的缓存指令,取决于我们的缓存碰巧热不热 ——
从 Google 角度看是随机的。
更要紧的是那个 3600:它和历史上从页面摘掉后换来 2.9 倍抓取量的是同一个值,
在 sitemap 这条路径上一直留着。它在对 Google 说「一小时内别再来取 sitemap」,
而「每天刷新 lastmod」想要的恰恰是它勤来取 —— 两件事互相抵消。
现在:蜘蛛池模式下 TTL 可配(默认 60 秒),命中与未命中用同一个缓存指令,
对外 max-age 严格等于内部 TTL。
> 站群 / 单站 / 泛目录模式逐字节不变,包括上面那个命中/未命中不一致的历史行为 ——
> 改动它会影响这些模式的对外表现,应当单独评估,不在本版范围内。
🔔 四条新告警
此前所有告警盯的都是「机器和服务有没有事」。但有几类故障发生时机器一切正常:
- ▸强引开着却没在生效 —— 配置显示开启,实际一条跳转都没产生。
- ▸抓取量断崖式下跌 —— 与自身基线对比,跌幅超阈值即报。
- ▸源站在 TCP 层拒连 —— 读内核
ListenOverflows 计数。这类失败根本到不了应用层,
应用日志里干干净净,而 Cloudflare 那边已经在报 521。
- ▸域名集体转黑 —— 昨天还有抓取、今天归零的域名批量出现。
阈值均可配置,填 0 即关闭该条。
📝 设置变更审计
后台保存系统设置从来没有写过操作日志。
曾经发生过关键开关被改动、事后无法追溯是谁改的、什么时候改的。现在补上了。
两个细节:
- ▸设置页每次保存都提交整张表单(几百个键),因此只记录真正发生变化的键。
- ▸敏感字段(密码 / 密钥 / Token)不回显明文,但附一段短指纹 ——
否则「密钥被换过」和「密钥没动过」在日志里长得一模一样,审计就失去意义。
🧪 验证
- ▸新增约 45 个单元测试。
- ▸关键模块全部通过变异测试自证(逐条把生产代码改坏,确认测试确实会失败):
sitemap 缓存策略 7/7、设置审计 11/11、告警与日志字段全部捕获。
一个盯「文章 URL 是否都走规范入口」,一个盯「是否有人直接读全局运营模式」。
- ▸门禁全绿:build / vet / 全量测试 / race 竞态检测 / 格式检查。
升级建议
建议所有部署升级,尤其是「蜘蛛量正常但收录上不去」的站点。
> ⚠️ 部分站点的文章 URL 会发生变化。 本版把七个生产者统一到同一套规则,
> 因此原先由 sitemap / 推送 / 互链产生的那批非规范 URL 会改为与页面 canonical 一致。
> 使用含日期或 {cid} 占位符的 URL 规则的站点,变化范围更大。
>
> 这正是修复的目的 —— 让挂出去的 URL 和自指的 canonical 对齐。
> 旧 URL 在默认配置(block_invalid_url = off)下仍可正常打开;
> 若把该项设为 404,建议升级后重新提交一次 sitemap。
升级后可关注两处:Search Console 里「替代网页(含适当的规范标记)」的数量应逐步下降;
蜘蛛统计中 robots.txt 与真实内容页的比例首次变得可查。