常见問题

入口頁里的目标 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 路由的站点结构——那種情况下,問题不在入口頁寫不寫 #,而在目标地址本身能不能被当作一個可獨立請求、可獨立阅讀的頁面。