第 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 | 返回 200 | HTTP 状态码 |
| INDEX | 没有 noindex | <meta name="robots"> 或 X-Robots-Tag 响应头 |
| INDEX | 有 title | HTML 里的 <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>)
现在就动手——
反馈回路本身就是这一课的精髓:
- 自检解析器(离线):
python3 tools/crawl_audit.py --demo - 审计一个能通过的页面——Google 自家的文档:
python3 tools/crawl_audit.py https://developers.google.com/search/docs/fundamentals/how-search-works - **现在审计一个你自己的页面。**然后故意把它弄坏:给一个测试页面加上
<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 方式不一样吗?”——追问是学得最快的方式。