有些蜘蛛池入口頁為了防采集或者图省事,目标連結不寫在 HTML 里,而是用 JavaScript 拼成字符串再插進頁面。在浏览器里点開一切正常,但換成搜尋蜘蛛来抓,這條發現路径會明顯變長,甚至直接断掉。
抓取分两步:先取源碼,再决定要不要渲染
搜尋蜘蛛處理一個頁面通常有两步:第一步是抓取,把服務器返回的 HTML 源碼下载下来;第二步是渲染,把頁面放進渲染队列执行 JS,拿到最终的 DOM。第一步里,它看到的只是一段 <script> 里的字符串,不是連結;只有走到第二步,連結才可能出現。
問题在于渲染队列的成本遠高于普通抓取,優先級更低,等待時間從几小时到几天都有可能。對于入口頁這種本身權重不高、又需要快速传递信号的頁面,這個延迟會直接影响目标 URL 被發現的节奏。
不同搜尋引擎的處理差別很大
- Google:渲染能力相對完整,但仍然要排队,且不保證每次都渲染。
- Bing:部分场景支持渲染,覆盖率不稳定。
- 百度:對 JS 渲染的支持有限,绝大多數情况下依赖源碼里的連結。
- 其他中小引擎:基本只讀源碼,不做 JS 执行。
換句话说,把連結交给 JS,等于把發現權交给了對方“愿不愿意為你跑一次渲染”。這不是一個可以稳定依赖的前提。
几種典型的“寫了等于没寫”
- 用 innerHTML 把 <a> 标簽拼進某個容器,源碼里只有容器空壳。
- 連結没有真實 href,只绑了 onclick 事件做跳轉。
- 頁面先出骨架,連結靠接口返回後再异步插入,蜘蛛拿到的是空列表。
- 用 document.write 輸出連結,容易在渲染阶段被覆盖或忽略。
- 連結放在 Shadow DOM 或閉包内部,渲染後也不一定暴露在可解析结构里。
這些寫法在浏览器里肉眼可见,在源碼里却搜不到目标 URL 的痕迹。入口頁的职责本来就是把發現路径缩短,一旦把連結藏進 JS,反而多设了一道關卡。
noscript 不是可靠的兜底
有人會把連結主要放在 <noscript> 里,指望不渲染时能讀到。實际效果並不稳定:部分引擎在開啟渲染後就不再讀取 noscript 内容,關閉渲染时又可能整段忽略。它最多算补充,不能当作主要通路来设計。
想保留 JS,也別让源碼里没有連結
- 能服務端渲染就服務端渲染,把包含連結的最终 HTML 直接返回。
- 源碼里至少保留一套静態 <a> 标簽指向目标 URL,JS 只做体驗增强。
- 連結使用真實 href,不要只靠点击事件跳轉。
- 避免把入口頁做成纯空壳,正文和連結先出,交互後加。
- 列表和翻頁用普通超連結,不要让“加载更多”按钮成為唯一的入口。
怎么驗證蜘蛛到底拿到没拿到
- 用搜尋引擎提供的 URL 检查或渲染測試,查看渲染後的 HTML 里有没有目标連結。
- 翻服務器日誌,確認搜尋蜘蛛是否真的請求過目标 URL,而不是只抓了入口頁。
- 把源碼和渲染後的 DOM 對比,看連結是不是只存在于後者。
- 如果日誌里目标 URL 長期没有任何抓取记錄,優先怀疑渲染這一环,而不是去調内容。
一個很简單的自检:把頁面源碼單獨複製出来,在里面搜一下目标 URL。如果搜不到,就不要預設搜尋蜘蛛一定能發現它。
小结
JS 動態插入連結並非绝對無效,但它属于“多一道關卡”的方案,适合有充足抓取预算和渲染容忍度的站点。對蜘蛛池入口頁這類以传递發現信号為主要任務的頁面,能直出就直出,把 JavaScript 留给确實需要交互的部分,連結的發現率會稳得多。