搜索抓取

锚点与 hash 路由:URL 里井号后面的内容,蜘蛛能看到吗

URL 里的井号常被当成链接的一部分,但服务端根本收不到它。本文说明锚点、hash 路由与蜘蛛抓取之间的差别,讲清什么样的锚点内链还有价值,以及前端路由把内容藏在井号后面时会带来什么后果,并给出把路由改回可抓路径的排查与调整思路。

搜索抓取

锚点与 hash 路由:URL 里井号后面的内容,蜘蛛能看到吗

URL 里常见一个井号,后面跟着一截内容。对普通用户来说,它常常只是“跳到页面某个位置”;对搜索蜘蛛来说,它基本等于不存在。理解这一点,能避免很多“链接明明放在页面上,蜘蛛却始终没来”的困惑。

井号后面不参与请求

浏览器发起请求时,HTTP 请求行里只有协议、域名、路径和查询串,井号及其后面的片段标识符由浏览器本地处理,不会发送给服务器。所以 example.com/a#part2example.com/a 在服务器看来是同一个请求,日志里记录的也只是井号之前的那一段。

  • 蜘蛛抓取 a 页面一次,就等于覆盖了它所有的锚点变体;
  • Sitemap 里写带锚点的地址,相当于重复提交同一页;
  • 用锚点区分的内容区块,不会形成独立 URL。

锚点内链还有没有用

有用,但作用在“页内跳转”和“语义上下文”上,而不是产生新 URL。目录、导航里的锚点链接能让蜘蛛更清楚地理解这一页的结构,锚文本里的关键词也能帮它判断这一段在讲什么。前提是目标内容真实存在于 HTML 里。

如果“展开更多”是靠点击后异步加载,锚点跳到的地方可能只是一个空容器,蜘蛛顺着跳过去也读不到内容。这类内容最好默认渲染在 HTML 中,或者提供一个可直达的独立 URL。

hash 路由是另一种情况

前端路由常见形如 /#!/detail/123/#/detail/123 的写法。服务端收到的永远是站点根路径,返回同一个壳页面。蜘蛛看到的是同一份 HTML,抓十次、一百次都一样,具体条目自然无法被发现。这既浪费抓取资源,也让大量内容停留在“不可发现”的状态。

可行的调整方向:

  1. 改用 History API,把路由映射成真实路径,服务端对每个路径返回对应内容;
  2. 或者保留前端路由,但做服务端渲染或预渲染,让蜘蛛拿到的 HTML 里就有内容和链接;
  3. 关键栏目再补一份静态可抓路径,例如列表页和详情页的服务端版本。

几个排查动作

  1. 翻日志时,确认蜘蛛请求的路径里是否出现过井号,正常情况不该出现;
  2. 用命令行工具直接请求带井号的地址,看返回内容是否与预期一致;
  3. 检查 Sitemap 和内链,把带锚点的地址替换为规范的页面地址;
  4. 检查是否存在 href="javascript:void(0)" 这类不产生请求的链接,它们对 URL 发现没有帮助。
锚点不是链接的替代品。要么给出一个真实的、服务端能响应的地址,要么就接受这部分内容暂时不会被独立发现。

把“内容存在”和“内容可被发现”分开看,很多抓取问题会变得简单:蜘蛛只能走它能请求到的地址。井号后面的东西,交给浏览器就可以了。