SEO·AEO 给开发者

第 0002 课 · crawl(抓取)+ index(索引)阶段

可抓取(crawlable)≠ 可索引(indexable)

两道彼此独立的门,两种彼此独立的失败模式。大多数"我的页面为什么不排名?"的问题 都死在这里——甚至还没轮到 rank(排名)登场。

回顾 第 0001 课:经典搜索按 crawl(抓取)→ index(索引)→ rank(排名)→ serve(投放)运行。今天我们放大看前两步——因为一个页面只要在任一步失败,就永远无法 rank(排名),而作为开发者,这恰好是你的工具能自动检查的两道门。

开发者常常把这两者混为一谈。“可抓取(crawlable)“和”可索引(indexable)“是相互独立的。一个页面可以完美可抓取,却仍然拒绝被索引。一个页面也可以被标记为”请索引我”,却从不被抓取。它们是两道不同的门,配两个不同的开关。[1]

你的收获: 运行一个脚本,让它审计任意 URL 通过这两道门的情况,并准确告诉你是哪一道在失败——这是对”这个页面到底能不能露面?“最紧的反馈回路。

两道门

CRAWL

bot 能取到它吗?

在页面被读取之前就受到控制。

  • robots.txt 必须允许该路径
  • URL 必须返回 200(而不是 404 / 5xx / 无限重定向)
  • 必须可被发现(出现在 sitemap 里或有链接指向它)
INDEX

引擎会留下它吗?

在被取到的页面内部受到控制。

  • 没有 noindex(meta 标签 X-Robots-Tag 响应头)
  • 有真实内容 + 一个 <title>
  • 有一个合理的 canonical(规范链接,标明哪个 URL 才是"正主")
把所有人都坑了的陷阱:robots.txt 里封禁一个页面并不会把它从索引里移除。如果 bot 被挡住、无法抓取,它就永远不到你的 noindex 标签——所以要让一个页面被取消索引(deindex),你必须允许抓取,并提供 noindex。封禁 + noindex 一起上 = noindex 永远不会被看到。[2]抓取控制和索引控制指向相反的方向。

检查清单,以及每一项由什么控制

检查项控制开关在哪里
CRAWL路径被允许/robots.txt
CRAWL返回 200HTTP 状态码
INDEX没有 noindex<meta name="robots">X-Robots-Tag 响应头
INDEX有 titleHTML 里的 <title>
INDEX有 canonical<link rel="canonical">

实操技能:用脚本审计一个 URL

你已经有它了——本工作区里的 tools/crawl_audit.py。只用标准库,无需安装。核心在于:urllib.robotparser 回答抓取这道门,一个极简的 HTML 解析器回答索引这道门。

# 核心所在 —— 先过 robots 门,再看 index 信号
def robots_allows(url):
    rp = urllib.robotparser.RobotFileParser()
    rp.set_url(origin(url) + "/robots.txt")
    rp.read()
    return rp.can_fetch("Googlebot", url)   # stdlib does the parsing

# index gate: noindex? title? canonical?  (from the page's <head>)
现在就动手——

反馈回路本身就是这一课的精髓:

  1. 自检解析器(离线):python3 tools/crawl_audit.py --demo
  2. 审计一个能通过的页面——Google 自家的文档:python3 tools/crawl_audit.py https://developers.google.com/search/docs/fundamentals/how-search-works
  3. **现在审计一个你自己的页面。**然后故意把它弄坏:给一个测试页面加上 <meta name="robots" content="noindex">,看着 INDEX 门翻成 FAIL,而 CRAWL 仍然通过。这种对比正是这一课要讲的。
$ python3 tools/crawl_audit.py https://developers.google.com/search/docs/fundamentals/how-search-works

Audit: https://developers.google.com/.../how-search-works
──────────────────────────────────────────────
[PASS] CRAWL · robots.txt allows the bot
[PASS] CRAWL · page returns success (200)
[PASS] INDEX · no noindex directive
[PASS] INDEX · has a <title>
[PASS] INDEX · declares a canonical URL
──────────────────────────────────────────────
VERDICT: crawlable + indexable. (Ranking is a separate fight.)

要知道的天花板:这是一次静态抓取。如果一个页面用 JavaScript 渲染(render)它的内容,urllib 就看不到——Google 会做第二轮渲染(render),而这个脚本跳过了那一步。那个落差(JS 渲染)是后面一整课的内容。

提取练习 · 不许偷看

哪道门,哪个开关?

凭记忆作答——正是这份努力让知识留得住。每题只有一次机会;在看其他选项前先选。

第 1 / 4
某个页面在 robots.txt 里被封禁,但没有 noindex。会发生什么?
第 2 / 4
你给一个同时列在 sitemap 里的页面加上了 noindex。结果如何?
第 3 / 4
某个页面完全可抓取,却从不出现在索引里。是哪个阶段在拦它?
第 4 / 4
你的脚本读取 X-Robots-Tag 响应头,是为了检测……
一手来源 — 接下来读这个 (≈10 分钟)
"用 noindex 阻止搜索索引" —— Google Search Central

直接点出了"封禁 vs noindex"的陷阱:一个被封禁的页面,它的 noindex 根本读不到。另可参阅 robots.txt 的入门介绍。

卡住了,或者好奇? 这个 agent 就是你的老师。尽管问——“给我看一个真实的 robots.txt”、“Claude 和 Perplexity 的 retrieve 方式不一样吗?”——追问是学得最快的方式。