新文章迟迟不收录的六层排查:爬虫日志验证、robots 与 noindex 冲突、抓取预算与内链孤岛

那些让人睡不着的收录问题

做中文站几年,最折磨人的不是技术故障,而是「页面明明在,就是搜不到」。你说它没收录吧,用 site:example.com 能查出来几条;你说它收录了吧,昨天发的那篇三天了还是「已发现,尚未编入索引」。更气人的是,同一批文章里有的当天就上了,有的半个月不动,你反复去 Search Console 请求编入索引,按钮点了一百次也没用。

我一开始以为这是「玄学」,后来花了几个月时间把站点的爬虫日志、Search Console 的抓取统计、页面本身的 HTML 三者对照起来看,才明白绝大多数「不收录」都有明确的技术原因,而且大部分原因根子在站内结构上,不在「权重」这种说不清的东西上。这篇文章把这些原因拆成六个可以逐条检查的层面,每一层都给出具体的判断方法和修复手段。这套流程我拿来处理过三个站,平均两周内把「已发现未索引」的堆积量降了七成以上。

第一层:先确认爬虫到底来了没有

所有判断的第一步都是日志。没有爬虫日志,后面全是猜。判断爬虫来没来,看 Nginx 日志里的 User-Agent 是不够的,因为 UA 可以伪造,而且大部分网站前面的 CDN 会把真实 IP 藏起来。正确的做法是用反向 DNS 验证:Googlebot 的官方 IP 段是固定的,反查 IP 得到的主机名必须以 googlebot.com 或 google.com 结尾,再正向解析回去必须得到同一个 IP。

# 从日志里找出所有声称是 Googlebot 的 IP
awk -F'"' '/Googlebot/ {split($1,a," "); print a[1]}' /var/log/nginx/access.log \
  | sort | uniq -c | sort -rn | head -20

# 逐个反查(示例 IP)
dig +short -x 66.249.66.1
dig +short 1.66.249.66.in-addr.arpa PTR

如果反查出来的主机名是 crawl-66-249-66-1.googlebot.com 这类,说明是真的。如果反查结果是 some-vps.example.ru 之类,那就是假的,它在偷偷抓你的内容。这一步做完你会得到两个信息:真实爬虫每天来多少次、都抓了哪些页面。

接下来看它抓了什么。把日志按路径聚合,看每次会话的分布:

# 只看 Googlebot 抓过的路径,按访问次数排序
awk '$0 ~ /Googlebot/ {print $7}' /var/log/nginx/access.log \
  | sort | uniq -c | sort -rn | head -50

如果这个列表里全是首页、分类页、标签页,而你新发的文章一次都没出现,问题就定位到了「爬虫根本没发现新 URL」。这种情况下再去看页面质量、内容长度都是浪费时间。反之,如果新文章的 URL 每天被抓十几次但状态一直是「已发现未索引」,那就是另一个问题了。

第二层:robots.txt 与 noindex 的自相矛盾

这一层的坑非常经典,表现为「想让收录的页面写了 noindex,不想收录的页面反而被索引」。检查方法很简单,但要逐页检查:

# 抓一个具体页面,检查 robots meta 与 canonical
curl -s "https://example.com/post/123.html" | grep -iE '<meta name="robots"|<link rel="canonical"|<meta name="googlebot"'

最常见的三种错误:

全站模板里带了 noindex。很多主题的「演示模式」或者「SEO 设置」里有一个开关,装主题的时候默认打开,站长根本没注意。表现是整站所有页面都带 <meta name="robots" content="noindex">,Search Console 里会大面积报「已被 noindex 标记排除」。

robots.txt 屏蔽了 CSS/JS 但页面又渲染依赖它们。现在搜索引擎都会渲染 JavaScript,如果 robots.txt 里写了 Disallow: /static/ 或者 Disallow: /*.js$,爬虫拿不到 CSS 和 JS,渲染出来的页面可能是空白或者错乱的,它就不会索引。更糟的是,Google 明确说了:如果页面被 robots.txt 屏蔽,它就无法读取页面上的 noindex,结果是「既进不来也无法被排除」,可能以裸 URL 的形式出现在结果里。

Disallow 与 noindex 同时使用。这是 SEO 领域最著名的自相矛盾:robots.txt 挡住了爬虫,爬虫就读不到 noindex,于是页面永远不会被真正移除。正确的做法二选一:要彻底移除用 noindex(且允许抓取),要节省抓取预算用 Disallow(但要接受它可能以 URL 形式存在)。

检查 robots.txt 还有一个细节,很多站会写:

User-agent: *
Disallow: /?s=
Disallow: /*?replytocom=
Disallow: /tag/
Allow: /tag/important-tag/

这里 Allow 写在 Disallow 后面是可以生效的(同长度前缀时更长者优先),但很多人误以为「Disallow 优先,Allow 无效」。实际规则是最长匹配优先,长度相同时 Allow 优先。搞清楚这条,就不用为了放行某个目录而把整个 Disallow 规则删掉。

第三层:抓取预算被无效 URL 吃掉

新站或者刚迁移的站,经常遇到「爬虫天天来,但都在抓垃圾页面」。这些垃圾页面主要来自四类:

带参数的 URL 无限组合。搜索页、分页、排序、筛选、跟踪参数,一个 ?page=1&order=asc&tag=x 就能组合出成百上千个 URL。修复分两步:robots.txt 里屏蔽带参数的模式;同时在页面上加 canonical 指向无参数的版本。

日历归档与作者归档。Typecho/WordPress 默认会生成 /date/2024/09/ 和 /author/admin/ 这类页面,内容与首页高度重复。要么关掉,要么加 noindex。

站内搜索结果页。这类页面几乎是无限生成的,而且内容质量低。除了 robots 屏蔽,还要确保搜索页返回 X-Robots-Tag: noindex 头,多一层保险。

被攻击产生的垃圾 URL。如果你发现日志里冒出大量 /wp-login.php、/xmlrpc.php、/ 后面跟随机字符串的请求,这些不是爬虫干的,是扫描器。但如果这些路径返回 200(比如被伪静态规则 catch-all 到了首页),爬虫也会跟着抓,于是每个垃圾 URL 都被当成有效页面。修复关键是让不存在的路径老老实实返回 404,而不是全部重写到首页。

抓取预算的量化方法:Search Console 的「抓取统计信息」里能看到按响应码分的抓取量。健康站点的 2xx 占比应该在 80% 以上,如果 3xx 和 404 占了一半,说明大量预算浪费在跳转和死链上,必须先清理再谈收录。

清理死链有个高效的做法,从日志里提取所有返回 404 的 URL,按来源页面归类,找出内链指向死链的地方:

# 最近一天的所有 404
awk '$9 == 404 {print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -40

然后逐个修:能恢复内容的恢复,确实要删的做 301 到最相关的页面,实在没有对应页面的就让它保持 404(不要 301 到首页,那叫软 404,Google 会识别并降权)。

第四层:内链结构决定爬虫能不能走到

新文章发了不收录,最常见的原因不是质量,而是没有任何页面链接到它。爬虫是沿着链接走的,一个只有 sitemap 里有、站内没有任何入口的页面,就是「孤岛页面」。它可能会被发现(通过 sitemap),但优先级极低,因为没有任何页面为它投票。

检查方法:把站内所有链接抓下来,和文章全集做差集。粗暴一点用爬虫工具,简单一点用日志——如果某个 URL 在日志里从来没有被访问过(除了 sitemap.xml 之外),它基本就是孤岛。

# 1. 拿到站点所有文章的 URL(以 Typecho 为例,从 sitemap 或列表页抓)
# 2. 在日志里过滤出这些 URL 的访问记录
# 3. 没出现在日志里的就是孤岛

# 快速版:看过去 7 天里每个文章 URL 被访问的次数
zcat /var/log/nginx/access.log.*.gz 2>/dev/null | cat - /var/log/nginx/access.log \
  | awk '$7 ~ /\/([0-9]+)\.html/ {print $7}' | sort | uniq -c | sort -n | head -30

排在末尾的那些,就是你该优先补内链的页面。补法有三条:

在相关文章里加正文内链。这是最有效的。写新文章时,主动回头看前面写过的同主题文章,挑两三篇在正文里自然地引用,锚文本用对方的核心关键词。双向都要做——新文章链向老文章(给老文章续命),老文章也要在合适位置补一条指向新文章(给新文章传递权重)。

用「相关推荐」模块。大部分主题都有,但默认逻辑往往是「同分类最新几篇」,这样新文章很快就能露出。如果主题的相关推荐是按随机或者按热度来的,新文章永远上不了榜,需要改逻辑或者加一个手动推荐的字段。

归档页与专题页。给每个主题做一个汇总页,把该主题下所有文章按逻辑顺序列出来,然后从导航或者相关文章里链过去。这既是内链枢纽,也是很好的长尾落地页。

这三件事做完,新文章的「入链数」从 0 变成 5 以上,收录速度的变化通常在一周到两周内能观察到。

第五层:内容层面的「低价值」判定

前面四层都通过了,页面还是「已发现未索引」,那就是内容被判为低价值。这一层的判断标准不公开,但从大量案例里能总结出几个明确的负面信号:

与已有页面高度重复。同一篇文章在多个分类下都有、或者列表页和文章页内容几乎一样(全文输出而非摘要),都会触发去重。检查方式:随机挑两个页面,对比正文相似度。列表页一定要输出摘要,不要全文。

正文太短,主要靠模板撑起来。一个 300 字的正文配上一大堆侧边栏、相关推荐、评论、广告,实际内容占比极低。中文站的经验阈值是正文不少于 800 字,我自己的标准是 1500 字以上,因为这样才有空间放真正的技术细节。

首屏全是广告或者弹窗。移动端尤其敏感。如果用户打开页面第一眼看到的是全屏广告,搜索引擎的移动友好性测试会直接判不合格。in-article 广告放在正文中间是可以的,浮层、插屏要慎用。

缺少明确的主题信号。标题、H1、description、正文首段、URL slug 都在说不同的事情。比如标题是「Nginx 配置」,H1 是「正文」,description 是空的,slug 是 /archives/123/。这种页面爬虫很难判断它到底在讲什么,自然不给好的位置。

修复这几条不需要什么技巧,就是把页面做「干净」:一篇页面只讲一件事、标题和 H1 一致、description 手写、URL 用英文或拼音 slug、正文有清晰的 H2 层级、把重复的模板内容(比如每个页面都一样的「关于本站」长段落)删掉或者折叠。

第六层:提交与验证的固定动作

前面五层是修根因,这一层是加速。顺序不能反——页面有硬伤的时候去提交,只会让搜索引擎更快地发现「这个页面不值得收录」。

Sitemap 要保持干净。只放 canonical 的、返回 200 的、需要被索引的 URL。不要放标签页、分页、搜索页。文章删除后要从 sitemap 移除。sitemap 的 lastmod 要真实反映内容更新时间,不要每次生成都写当前时间——那样爬虫会认为你在刷,逐渐降低对这个字段的信任。

用 IndexNow 加速必应和 Yandex。这是目前最有效的主动推送方式,一条 HTTP 请求就能通知对方「这个 URL 变了」。需要先在站点根目录放一个密钥文件,然后 POST 过去:

curl -X POST "https://api.indexnow.org/indexnow" \
  -H "Content-Type: application/json; charset=utf-8" \
  -d '{
    "host": "example.com",
    "key": "你的32位密钥",
    "keyLocation": "https://example.com/你的32位密钥.txt",
    "urlList": ["https://example.com/post/123.html"]
  }'

发布流程里把它接上,每发一篇自动推一次,比手动去后台点提交省事得多。注意 IndexNow 对同一 URL 短时间内重复推送是无效的,别写成循环。

Search Console 的 URL 检查只用一次。对同一个 URL 反复点「请求编入索引」,除了浪费配额没有别的作用。正确的用法是:确认页面没有硬伤之后点一次,然后等 5~7 天,观察状态变化。如果一周后还是「已发现未索引」,说明前面某一层还有问题,回去继续查。

建立每周的收录巡检。我给自己定的动作是每周一看三个数:过去七天新增页面数、新增页面已索引数、以及「已发现未索引」的总量变化。如果新增 20 篇但索引 0 篇,立刻停下写文章的动作去查原因——继续写只会堆积更多未被索引的页面。

# 用 Search Console API 拉「已发现未索引」的 URL 列表(需服务账号鉴权)
# 关键字段:pageUrl / verdict / coverageState
# 拉回来之后按 coverageState 分组,看哪一类占大头

把这六层做成一张检查表

最后把我实际用的顺序整理成一张表,遇到「不收录」的时候从上往下走,一层一层排除:

一、日志里有没有真实的 Googlebot?没有 → 查 DNS、CDN 是否拦截、服务器防火墙。有 → 下一层。

二、新 URL 有没有被抓过?没抓过 → 查 sitemap、内链入口。抓过 → 下一层。

三、抓到时返回什么码?3xx/4xx/5xx → 修跳转链、补 404 处理。200 → 下一层。

四、页面上的 robots meta 和 canonical 对不对?有 noindex 或 canonical 指向别处 → 修模板。正常 → 下一层。

五、站内有没有入链?入链为 0 → 补内链、做专题页。有 → 下一层。

六、内容是否重复/过短/模板占比过高?有 → 改写、合并、加内容。都没有 → 时间问题,等,并按周复查。

这套流程的好处是它把「玄学」变成了可验证的工程问题。大多数情况下走到第三层就能找到原因,剩下的往往不是技术问题,而是需要内容本身再厚一点。做站久了会发现,收录这件事的本质是「让搜索引擎确信这个页面值得占用它的一个索引位」——技术层面把障碍清干净,剩下的事就交给内容。

Last modification:October 18th, 2026 at 09:24 pm

Leave a Comment