常见问题

入口页里的目标 URL 带 # 片段,搜索蜘蛛会怎么处理?

入口页链接带 # 片段时,搜索蜘蛛通常会把片段剥离,按真实地址请求,同页不同片段也不会重复抓取。但如果目标站用 hash 路由,服务器收到的仍是外壳页面,内容靠 JS 渲染,抓取器可能拿不到正文,也就难以形成独立 URL。本文讲清片段的处理规则、常见误区和验证方法。

常见问题

入口页里的目标 URL 带 # 片段,搜索蜘蛛会怎么处理?

在蜘蛛池入口页里放目标链接时,有时会顺手带上锚点,比如 example.com/article#part2,或者单页应用的 example.com/#/detail/123。这种带 # 的 URL,搜索蜘蛛会怎么处理,会不会因此抓不到目标地址,是不少人问过的问题。先说结论:大多数情况下,搜索蜘蛛会把 # 及其后面的内容当作页面内的定位标记,而不是一个新的 URL。

# 后面的内容不会发给服务器

HTTP 请求本身就不包含片段标识符(fragment)。浏览器访问 example.com/page#section2 时,实际发给服务器的请求只是 example.com/page,服务器看不到 #section2 这一截。搜索抓取器遵循同样的规则,它发出的请求里不会带 # 后面的部分。所以只要入口页里的链接去掉片段后指向同一个地址,抓取器请求到的就是那个真实资源。

同页不同片段会被合并成一个 URL

在 URL 归一化环节,片段通常会被剥离。可以这样理解:

  • example.com/page、example.com/page#a、example.com/page#b 一般被视为同一个 URL;
  • 入口页里把这三条链接都放一遍,不会让目标地址被多抓两次;
  • 抓取预算也不会因为你多写了几个 # 就多分出来。

想靠给同一个地址加不同 # 来“多引几次蜘蛛”,基本是无效操作,反而让入口页显得杂乱。

真正会出问题的是 hash 路由

如果目标地址是单页应用,靠 # 切换路由,例如 example.com/#/list 或 example.com/#/detail?id=9,情况就不一样了:

  • 服务器收到的请求仍然只是站点根路径,返回的通常是同一份 HTML 外壳;
  • 正文由前端 JS 在浏览器端渲染;
  • 抓取器能否拿到渲染后的内容,取决于它是否执行 JS、渲染是否成功、内容是否在首屏可见。

这时入口页里放带 # 的链接,抓取器确实会去请求,但拿到的很可能是一个空壳,这些内容也不会被当成独立页面来处理。

确实要用 hash 路由的站点怎么办

  1. 优先改成 history 模式,让每篇内容有独立的可请求地址;
  2. 短期无法改造时,为关键内容补一份静态 HTML 或服务端渲染版本,让抓取器至少能读到正文;
  3. 在入口页里同时提供几条指向静态地址的普通链接,不要只依赖 hash 地址。

入口页写法上的几个建议

  1. 链接直接写最终要被抓取的那个地址,不要为了好看额外加锚点;
  2. 需要锚点跳转时,把带 # 的链接当作站内导航使用,别指望它带出新 URL;
  3. 同一个目标地址在入口页出现一次就够了,重复堆叠没有额外收益;
  4. 投放前先确认目标页面在无脚本环境下是否有可读内容。
想知道链接到底有没有被真正请求,看服务器访问日志最直接——你会发现日志里从来没有 # 后面的部分。

怎么验证

  • 查看访问日志里请求的完整路径,和入口页写的链接做对比;
  • 用抓取工具或日志分析脚本模拟请求,观察返回内容是否为空壳;
  • 对单页应用,用“查看网页源代码”而不是开发者工具,确认 HTML 里是否真的有正文。

小结:# 片段在抓取层面基本是透明的,它既不会帮你多要一次抓取,也不会打断对真实地址的请求。真正需要警惕的是把内容完全交给 hash 路由的站点结构——那种情况下,问题不在入口页写不写 #,而在目标地址本身能不能被当作一个可独立请求、可独立阅读的页面。