不少人做入口頁时习惯先给一個静態骨架,再用 JavaScript 把目标連結插進 DOM。頁面在浏览器里看起来連結齐全,但搜尋蜘蛛看到的可能是另一回事。结论先给:能不能被發現,取决于連結最终有没有出現在蜘蛛抓取並渲染後拿到的内容里,而不是取决于你在浏览器里能不能点到。
蜘蛛拿到頁面後大致會做两件事
一件是直接讀服務端返回的 HTML 源碼,另一件是按自身能力去执行頁面里的 JavaScript,再把渲染後的结果拿来解析。不同搜尋引擎、不同抓取场景(尤其是资源配額紧張的时候)對第二件事的投入差別很大。所以 JS 插入的連結属于“可能被發現,但不确定性明顯更高”的一類。
哪些寫法相對容易被發現
- 連結直接寫在服務端返回的 HTML 里,無论是静態輸出還是服務端渲染,這是最稳的一類。
- JS 只做增强:連結本身已经在 HTML 中存在,脚本只负责排序、折叠、懒加载。蜘蛛讀到源碼就已经拿到目标地址了。
- 頁面加载後立即同步插入、不依赖任何用戶交互,並且渲染抓取确實被执行到,也有机會被發現。
哪些寫法基本指望不上
- 必须点击按钮、滚動到某個位置、悬停之後才触發的插入,绝大多數抓取不會模拟這些交互。
- 依赖登入態、Cookie 或本地缓存才有資料的接口。
- 用定时器拖很久,或者等一串接口串行返回後才寫入連結。
- 地址由脚本在執行时拼接,且拼接逻辑依赖随机數或時間戳,即使执行了也可能每次都不一样。
判断方法:別用浏览器看,用源碼看
最常见的誤判,就是打開開發者工具看到 Elements 面板里連結整整齐齐,就認定蜘蛛也能看到。那個面板顯示的是渲染後的 DOM,不等于服務端返回的源碼。
- 用“查看網頁源代碼”(不是“审查元素”)確認目标連結是否出現在初始 HTML 中。
- 用命令行抓一次入口頁源碼,或配合禁用 JS 的抓取方式,看返回内容里有没有目标地址。
- 對照入口頁訪問日誌,確認蜘蛛請求入口頁之後,有没有紧接着請求目标 URL,而不是只抓了入口頁就离開。
- 如果頁面大量依赖 JS,可以看站長平台提供的渲染後快照或抓取诊断信息,判断渲染是否真的被执行。
更實用的做法
如果你在运营蜘蛛池,入口頁的首要任務是让目标 URL 出現在容易被讀到的位置,那就没必要把發現鏈路的可靠性押在脚本执行上。
- 目标連結尽量以普通 a 标簽寫在服務端輸出的 HTML 中,脚本只做锦上添花。
- 确實需要動態生成时,至少留一份静態兜底列表,和動態内容放在同一個頁面里。
- 控制單個入口頁的脚本复杂度,减少串行請求和長延时。
- 不要把隐藏連結、交互後才出現的内容当作唯一的暴露渠道。
几個容易混淆的点
JS 插入的連結和 JS 跳轉不是一回事。前者是頁面里存在一個可解析的連結,後者是頁面打開後直接跳走,蜘蛛是否跟進要看具体實現。用 noscript 内容兜底也有用,但它只在脚本不执行时才生效,不能替代正常輸出。還有一種情况是連結确實在源碼里,但被包裹在一大段脚本字符串中,虽然文本搜得到,能否被当作連結解析仍要單獨驗證。
记住一個判断标准:把頁面源碼(不是渲染後的 DOM)儲存下来,用文本搜尋目标 URL,搜得到才叫“稳”,搜不到就只能算“有机會”。