整理投放链接时经常会碰到带 # 的 URL,比如页面内的锚点定位 .../help#step3,或者单页应用里的 .../#/detail/1001。这类链接投进蜘蛛池或提交入口后,日志里往往看不到预期的抓取,于是怀疑投放没生效。多数情况下,问题不是出在蜘蛛池,而是 # 号后面的内容并不参与 URL 识别。
一、先分清 # 后面是锚点还是路由
同样是 #,含义差别很大:
- 页内锚点:# 后面是某个元素的 id,打开后浏览器滚动到对应位置,页面内容与不带 # 的版本基本一致。
- hash 路由:# 后面是前端路由路径,页面内容由 JS 根据这段路径渲染出来,服务端通常返回同一个 HTML 骨架。
- 带参数的 hash:类似 #!key=value 的写法,多出现在早期单页应用,本质仍归到上面第二类。
二、搜索蜘蛛看到的是什么
抓取时,客户端向服务器发起的请求一般只包含 # 之前的部分。也就是说,请求 .../help#step3 和请求 .../help,在服务器日志里是同一条记录,日志里不会出现 #step3。蜘蛛能拿到的,是不带 # 的那份响应。
对于 hash 路由页面,如果搜索引擎愿意渲染 JS,理论上能看到 # 后面那段路径对应的内容;但在 URL 层面,带 # 和不带 # 通常仍被当作同一个地址处理,不会自动变成两个独立页面。
把带 # 的链接当作“新 URL”来投放或提交,是常见的误操作:蜘蛛去访问的仍然只是 # 前面的那个地址。
三、投放这类链接时会遇到什么
- 日志里只能看到不带 # 的请求,误以为“没抓到”,其实是地址被截断了。
- 如果 # 前面的地址已经被抓过,重复投放往往不会带来新的抓取行为。
- 用带 # 的链接做外部入口,能传递的发现价值会打折,因为对外可识别的还是前缀地址。
- 统计时把 #/a、#/b 当作两个页面,容易高估覆盖量,实际只对应一个可抓地址。
四、希望 hash 路由页被发现,可以这样做
- 能用真实路径就用真实路径,把 #/detail/1001 改成 /detail/1001,让每个内容有独立的可请求地址。
- 改为真实路径后,服务端要为该路径返回可读内容,或至少做预渲染、服务端渲染,避免返回空壳。
- 站内链接统一使用不带 # 的规范地址,减少同一内容出现多种写法。
- 确实要保留 hash 路由的,至少让不带 # 的入口页可正常抓取,并在页面里以普通链接形式列出可访问的目标地址。
- 提交 sitemap 或投放列表时,使用去掉 # 及其后内容的规范 URL。
五、排查时可以先确认三件事
- 服务器日志里出现的地址,是带 # 的还是被截断后的版本。
- 同一个 # 前缀地址,是否已经有过抓取记录。
- 目标内容是否需要 JS 渲染才能出现,未渲染时页面里有没有可跟随的链接。
把这三点确认清楚,基本就能判断问题出在 URL 写法还是抓取环节。URL 结构规范一些,蜘蛛发现新页面的路径也会更顺,但具体抓取和收录仍由搜索引擎决定,无法通过投放来保证。