不少站点改用前端框架之後,導航、列表、分頁都由脚本生成。對用戶来说没差別,對蜘蛛却可能意味着两套完全不同的頁面:一套是服務器返回的原始 HTML,另一套是执行脚本後渲染出来的 DOM。連結到底出現在哪一套里,直接决定了 URL 能不能被發現。
蜘蛛拿到的第一份 HTML,才是發現連結的主场
蜘蛛請求一個 URL,最先拿到的是服務器返回的原始 HTML。這份内容里如果已经寫了 a 标簽的 href,連結就能在第一時間被發現,並進入待抓取队列。如果導航、列表、分頁的連結都要等脚本跑完才出現,那么這一次抓取里,蜘蛛看到的就是一個几乎没有出鏈的頁面。
结果通常有两種:要么這些 URL 只能靠 Sitemap 或外鏈慢慢被發現,要么一直没被發現。所以第一個判断動作很简單——把頁面原始 HTML 里所有 a 标簽的 href 抓出来,看看最重要的那批 URL 是否在里面。
渲染不是免費的:有队列,也有超时
主流搜尋引擎會對部分頁面做渲染,但渲染是額外一步,需要消耗资源,因此存在排队和超时。頁面脚本太重、依赖多個接口、首屏迟迟不出内容,都可能让這次渲染在完成前被放弃,最终只留下一個空壳頁面參與後續處理。
一個實用的心態:把渲染看成額外一次机會,而不是保底方案。最關键的連結和内容,尽量在第一份 HTML 里就给出来。
几種容易让連結隐身的寫法
- 用 div 或 span 挂点击事件代替 a 标簽,跳轉逻辑寫在脚本里;
- 導航和列表在接口返回後才插入 DOM,原始 HTML 中只有一個空容器;
- “加载更多”必须点击才請求下一頁,且没有可訪問的分頁 URL;
- 卡片、图片用懒加载占位,真實地址寫在自定义属性里;
- 列表資料由前端拉取後整体渲染,HTML 中不含任何明细連結。
這些寫法對用戶体驗未必差,但會让 URL 的發現路径變窄。可以改成:外层用真實的 a 标簽指向可訪問的 URL,脚本只负责增强交互,這样即使渲染失敗,連結依然在。
一次自查:两份頁面各有多少條連結
- 用抓取工具或命令行直接取原始 HTML,統計其中的 a 标簽數量;
- 在浏览器里查看渲染後的 DOM,再統計一次;
- 對比两個數字。如果原始 HTML 里連結寥寥無几,渲染後却有上百條,說明 URL 發現嚴重依赖渲染;
- 再從訪問日誌里找渲染請求,確認蜘蛛是否稳定地走到這一步。
這個對比不需要复杂工具,手工抽查几個栏目頁和列表頁就能看出問题集中在哪一层。
更稳的几條做法
- 主導航、面包屑、栏目入口這類结构性連結,由服務端直接輸出;
- 分頁保留真實可訪問的 URL,而不是只靠脚本拼接參數;
- 把重要 URL 同步進 Sitemap,给出一條不依赖渲染的發現路径;
- 控制首屏脚本体积和接口數量,降低渲染超时的概率;
- 上线後用日誌复核實际抓取情况,別只看工具里的渲染截图。
小结
URL 發現這件事,越靠近原始 HTML 越可靠。脚本可以增强体驗,但不要让“連結是否存在”取决于脚本能否跑完。把结构性入口放在第一份 HTML 里,再配合 Sitemap 兜底,蜘蛛的抓取路径才不至于断在半路。