「新文章发了三天,站长平台后台显示已提交,可搜索里搜标题还是搜不到。」这是站长群里出现频率最高的一句话。问的人往往已经做了三件事:提交 sitemap、点了「抓取诊断」、在搜索框里 site: 查了一下。三件事都做了,还是没收录,于是结论就落到「被降权了」或者「站被针对了」。这篇讲的是中间那条几乎没人走的路径:主动查看抓取状态,把「已发现未抓取」「已抓取未编入索引」「已编入索引但不可检索」这三种状态分开,然后针对每一条去动手。
一、三种「没收录」完全不是一回事
普通搜索框搜不到,只能证明「当前这个关键词下没排上」。收录问题的真正诊断入口是站长平台里的 URL 检查工具(Google 的「网址检查」、必应的「URL 检查」、百度的「抓取诊断」)。把具体 URL 贴进去,会得到一个明确的状态,大致分四类:
第一类,URL 未被发现。说明站内没有可被爬虫看到的入口链接,sitemap 也没提交或者提交了但没被读。这类问题在站内就能解决,不需要等。第二类,已发现但未抓取(Discovered - currently not indexed)。爬虫知道有这个地址,但还没来。第三类,已抓取但未编入索引(Crawled - currently not indexed)。抓了,读完觉得不值得收。第四类,已编入索引但当前无法显示(Indexed, though blocked by robots.txt 或者被 noindex 排除)。前两类是「时间问题 + 发现路径问题」,后两类是「质量问题 + 配置问题」,处理手段完全不同。
很多人卡在第二步,看到「已发现未抓取」就每天点一次「请求编入索引」。这个按钮的额度是有限的,而且它只是插一个队,不改变抓取预算本身。真正该问的是:为什么它排不上队。
二、判断是站太小还是页面不值得抓
先算一个数:最近 28 天爬虫抓了你多少页、其中有多少是新页面。这个数据可以在爬虫统计里看到(Google 的「抓取统计信息」、必应的「抓取信息」)。如果抓取总量每天只有几十次,而站里有几千个 URL,那这就是典型的「预算不够」,任何针对单页的催抓都是徒劳,方向应该是减少低价值 URL、加大高价值页面的内部链接密度。
反过来,如果每天抓几百次,但新发布的文章依然卡在「已发现」,那问题多半在「发现路径太深」。一个站只有首页、分类页、归档页三条路能进到文章,而首页每次只显示 10 篇,那么一篇文章在首页停留的时间可能不到一天,之后再进来只能靠归档页——归档页如果本身没被经常抓,这篇文章就永远沉底了。这类问题的解法很具体:给每篇文章加一个「相关文章」区块(自然产生横向链接)、把归档页提交进 sitemap、在最新文章列表里保留更多条数。2151 那篇讲 AI 爬虫的时候提过,爬虫的行为是可观测的,这里用的是同一套观察方法。
三、看日志,别只看后台
站长平台的数据有延迟(Google 通常 2 到 3 天,必应更短但统计口径不同,百度则需要主动去看抓取诊断)。最快的判据其实在自己服务器上——access log 里有没有那个 UA 来过。一条命令就能统计出最近几天各搜索引擎的抓取量:
zcat -f /var/log/nginx/access.log* \
| grep -oE 'Googlebot|bingbot|Baiduspider' \
| sort | uniq -c更细一点,看某个具体 URL 被谁抓过、抓的时候返回了什么状态码:
zcat -f /var/log/nginx/access.log* \
| grep '/2170.html' \
| awk '{print $1, $4, $6, $7, $9}' | tail -20这里有一个高频陷阱:日志里看到 200,不等于爬虫看到了完整页面。如果站点用了 CDN 或者反向代理,日志里的 status 是源站返回的,而爬虫拿到的是 CDN 的版本;如果 CDN 缓存了一份错误页,日志会显示「一切正常」而爬虫天天吃错误的缓存。判据是抓一次带 ?_= 时间戳的 URL,对比不带参数的结果——这两者不一致,问题就在缓存层。2185 那类缓存键的问题在这里会直接表现为「收录卡住」。
第二个陷阱是 304。爬虫带 If-Modified-Since 来请求,源站回 304 是完全正常的,但如果长期对同一个 URL 只回 304,而页面内容其实变过(比如模板更新了),爬虫就会认为没变化,不更新索引。这种情况在静态化站点上尤其常见:源文件没动,但模板动了,lastmod 也没更新。修法是让 lastmod 真正反映内容变更,而不是构建时间。
四、被 noindex 和 robots 拦下的两种静默失败
「已编入索引但被 robots.txt 阻止」,这行状态其实是矛盾的——如果 robots.txt 真的阻止了,页面根本不会被编入索引。出现这个状态通常说明:先被收录了,后来 robots.txt 才加上了 Disallow。爬虫不再抓取,也就看不到页面上是否有 noindex,于是索引里留着一条过期记录,永远不会被清理。
这是一个非常隐蔽的坑,因为它的表现是「页面明明存在,搜关键词也能看到旧标题,点进去却是 404 或者内容不对」。修法只有一条:先不要 Disallow,让爬虫能进来读到 noindex,等它读到了、索引掉了,再考虑是否 Disallow。顺序反了就要等几个月。
同理,X-Robots-Tag 响应头如果配错(尤其 add_header 在 location 块里继承丢失或者被覆盖的问题,2157 那篇提过同类机制),会让整批页面被标记 noindex 而站内毫无察觉。定期抽查几条重要 URL 的响应头是必要的:
curl -sI "https://www.example.com/2170.html" | grep -iE 'x-robots|content-type|age'看到 noindex 而自己并没有配置,就要去查是 CDN、WAF 还是安全插件加上去的。这类第三方层面加上去的头,往往连自己人都不记得。
五、抓了但没索引:内容侧的三条硬判据
「已抓取但未编入索引」是最容易被误解的状态。它不代表页面有技术错误,而代表搜索引擎在多个相似页面里选了别人。以下三条判据基本能覆盖八成情况。
第一,页面是不是和站内其他页面高度重复。比如同一篇文章出现在首页、分类页、标签页、归档页,且这些聚合页都输出了完整正文。这时候搜索引擎会挑一个做代表,其余全部归为重复。判据很简单:随机抽两个聚合页,看它们和文章页的正文重合度。修法是把聚合页的正文改成摘要(保留一两段),或者给聚合页加 canonical 指向文章页。这个动作往往一次就能让一批页面从「未编入索引」转成已收录。
第二,页面是不是「薄」。三个标签页、只有一张图、没有正文的页码页,本来就该不被收录。与其花时间催它收录,不如把它设成 noindex, follow,让抓取预算流到有内容的地方。判断一个站有没有「薄页面泛滥」,可以看 sitemap 里的 URL 数除以文章总数,超过 3 倍就值得审视。
第三,页面上的主要内容是不是靠 JS 渲染。如果正文要靠前端请求接口才出现,而接口被 robots.txt 挡了或者需要登录,爬虫看到的就是空页面。判据是 curl -s URL | grep -c '正文里一个独特短语',返回 0 就说明正文不在 HTML 里。修法优先做服务端渲染或者预渲染,而不是指望爬虫执行 JS。
六、请求编入索引的正确用法
这是被滥用最多的功能。它的正确用法是「新发布的重要页面,发现慢的时候点一次」,而不是「每篇都点,每天点」。额度用完之后按钮会变灰,而用掉的额度并不会在你这里记录,所以很容易出现「点了没反应但其实额度已经没有了」的困惑。
比按钮更持久的做法是提交 sitemap 并保持 lastmod 真实,同时保证站内有入口。sitemap 有一个很多人不知道的性质:它本身也是爬虫发现新页面的主要路径之一,一份更新及时、只包含有价值 URL 的 sitemap,效果远好于反复点按钮。另外,百度与必应都支持主动推送(IndexNow 协议),这条路在 2118 那篇里讲过,对新页面是最快的手段之一——但同样,推送不等于收录,它只负责「让它知道」。
七、一个可以照着走的排查顺序
把上面这些整合成一个固定顺序,遇到「没收录」就这么走,别凭感觉。
第一步,URL 检查工具看状态。这一步决定后面走哪条分支,不能跳过。第二步,看日志确认爬虫有没有来过、拿到的是什么码、有没有被 CDN 缓存影响。第三步,如果来过但状态是「已抓取未索引」,用 curl 抽查正文是否真在 HTML 里、响应头有没有 noindex、聚合页是否重复。第四步,如果根本没来过,看 sitemap 是否包含这个 URL、站内入口深度是否超过三层、文章列表页是否保留了足够多的旧文章链接。第五步,以上都正常,把这件事放下一到两周再看——很多时候只是慢,而不是坏。
最后一句经验:收录慢这件事,绝大部分时候原因在站内结构,不在搜索引擎的态度。把「是不是被惩罚了」这个问题换成「爬虫为什么不愿意花预算在这里」,答案通常一周内就能找到,而且找到之后往往能一次性解决一批页面,而不是只解决眼前这一篇。