把連結交给 JavaScript 生成,是目前入口頁最容易踩的坑之一。搜尋引擎的抓取流程和用戶打開浏览器並不完全相同,理解這個差別,才能判断目标 URL 到底有没有机會被發現。
抓取通常分成两步
搜尋引擎取回一個 URL 时,第一步拿到的是服務器直接返回的原始 HTML。這一步不执行脚本,頁面里寫了什么就是什么。如果連結全部由 JavaScript 在執行後插入,原始 HTML 里就只有一個空容器,蜘蛛在這一步看不到任何可跟的連結。
第二步是渲染。引擎會把頁面放進一套無头浏览器环境里执行脚本,再從中提取渲染後的連結。這一步确實存在,但它有排队、超时和资源配額的限制。渲染成功是概率問题,不是必然结果,所以「能被渲染」和「一定被渲染到」是两回事。
三種常见寫法的差別
服務端渲染或预渲染
連結在服務器返回的 HTML 里就已经存在,蜘蛛第一步就能看到,也就能顺着抓下去。這是最省心的做法,入口頁連結尽量用這種方式輸出。
纯客戶端渲染
首屏 HTML 往往是一個空容器加一段脚本,連結要等接口返回資料後再插進 DOM。這種方式對抓取最不友好:渲染队列稍有延迟或失敗,連結就等于不存在。入口頁如果承担分發連結的职责,不建议用這種方式。
异步接口拼接
頁面先渲染出结构,再通過接口請求拿連結資料。它比纯客戶端渲染好一点,但依然依赖脚本成功执行。如果接口需要額外鉴權、依赖 Cookie 或跨域被拦,渲染时同样拿不到連結。
怎么驗證自己的入口頁
- 關掉浏览器 JS,或者直接用命令行取回 HTML,看源碼里有没有可点的 a 标簽。
- 用搜尋後台的 URL 检查類工具,對比「已抓取的 HTML」和「渲染後的 HTML」是否一致。
- 翻服務器日誌:入口頁被訪問之後,目标 URL 的抓取請求有没有跟着出現。
- 检查 robots.txt 是否屏蔽了 JS、CSS 等渲染资源。资源被挡,渲染出来的结构可能和用戶看到的完全不同。
更稳妥的處理顺序
- 把關键連結放進服務端輸出的 HTML 里,這是成本最低、最可控的做法。
- 如果前端框架無法避免,就做预渲染或 SSR,让首屏源碼里带上連結。
- 保留一份静態連結頁或 sitemap 作為兜底,不要让 JS 成為唯一通道。
- 確認目标 URL 本身可被抓取、返回正常狀態碼,否則入口頁做得再好也没用。
別指望的几件事
渲染队列不是實时服務,也不承诺處理每個頁面。把入口頁的唯一發現通道押在 JavaScript 上,等于把一個可控問题變成一個不可控問题。
如果發現目标 URL 長期没有被抓取记錄,先按「原始 HTML 里有没有連結」這條线排查,往往比反复調整蜘蛛池參數更有效。連結能在源碼里被看到,後面的抓取才有讨论的基础。