頁面在浏览器里点着一切正常,抓取工具却可能一條 URL 都拿不到。這類問题多半不出在服務器或 robots.txt,而是連結本身没寫成可解析的形式:地址只存在于 JavaScript 执行後的 DOM 里,或者绑在一個点击事件上。
連結寫法為什么會决定 URL 的發現结果
搜尋蜘蛛發現新 URL 的主要途径,仍然是顺着頁面里已有的連結往下走。它能處理的是 HTML 响應体中可以直接解析出目标地址的連結;如果地址要等脚本跑完才出現,這條 URL 就多了一道门槛——需要等待渲染,而渲染有成本和次數限制,也並不保證每次都會發生。能被 HTML 直接给出的連結,是最稳的那一類入口。
這也是為什么同一個站,不同模板的詳情頁發現速度差很多:模板 A 的列表頁是静態 a 标簽,模板 B 靠前端路由拼接,二者在抓取工具眼里的可發現性並不對等。
几種常见連結寫法的差异
标准 a 标簽加 href
把地址寫在 href 属性里,是最直接的形式。它與用戶是否点击無關,抓取工具讀一次 HTML 就能拿到。相對路径和绝對路径一般都能解析,但同站内部建议统一風格,避免拼接出错。锚文本不必多讲究,關键是 href 指向的地址真實可訪問。
- 連結文字或图片被 a 包裹都可以,判定依據是 href
- 列表頁、面包屑、相關推荐都是自然的入口位置
- 同一頁重复指向同一地址时,收敛成一個入口即可
JS 路由與 onclick
前端路由、onclick 跳轉、javascript:void(0) 配合 data 属性,都會让目标地址藏在脚本里。地址在源碼中可能以字符串形式存在,但缺少明确的連結语义,抓取工具未必會把它当成一條待抓 URL。
判断办法很直接:禁用 JS 後打開頁面源碼,看目标地址是否出現在 href 中。如果不在,就不能預設它會被發現。對于确實想被發現的頁面,比較稳的做法是补一條普通的静態連結,或者把它放進 Sitemap,作為另一條獨立通道。
图片、按钮與伪連結
用 div、span 加样式做成的“連結”,或者整块图片热区,在没有 a 标簽包裹时同样不构成連結。按钮配合表單提交跳轉、下拉菜單内的選項,也属于這一類。它們對用戶体驗没影响,但對 URL 發現是空白的。
自查連結可發現性的几個步骤
- 挑一個典型模板頁,關閉 JavaScript 後查看源碼,搜尋目标 URL 的關键片段。
- 用抓取工具拉一次原始 HTML,確認响應体里是否存在带 href 的連結。
- 把服務端日誌里已被訪問的詳情頁地址,與頁面 HTML 中實际出現的連結做對比,找出“日誌里有、源碼里没有”的那批。
- 對只在渲染後出現的連結,评估是否值得补一條静態入口,或單獨整理進 Sitemap。
- 按模板分组重复以上動作,避免只看了首頁就下结论。
與 Sitemap、内鏈结构的配合
Sitemap 是連結之外的补充通道,适合放那些内鏈不好安排、或者层級較深的頁面。但它不應该成為唯一入口:如果全站詳情頁都只靠 Sitemap 提供地址,一旦 Sitemap 更新延迟或抓取失敗,這批 URL 的發現就會同步停摆。更稳妥的结构是——列表頁與内鏈负责日常發現,Sitemap 负责兜底與批量声明,两條路各走各的,互不依赖。
内鏈方面,不必追求每個頁面都有几十個入口,重点是別让重要頁面成為孤岛。一個頁面如果既没有站内連結指向它,也没出現在 Sitemap 里,被抓取工具碰巧發現的概率就很低。
几個容易忽略的细节
- 带 # 的锚点連結,井号後面的部分不构成新的 URL,只是同一頁面内的位置标记。
- 嵌在 iframe 里的連結,是否能被抓到取决于頁面可訪問性,不要把它当作主要入口。
- rel="nofollow" 影响的是連結關系的传递,並不等于阻止發現,別把它当成屏蔽工具使用。
- 連結地址本身要能正常返回,若落点長期是 5xx 或经過多次跳轉,即使被發現也很难稳定抓取。
- 移動端與桌面端模板不一致时,要分別確認各自的連結寫法。
連結寫法的核對成本很低,收益却稳定:先確認地址在不在 HTML 里,再谈抓取频率和抓取预算。發現不了,後面所有優化都没有入口。