很多人在做入口頁的时候,為了省事或者為了控制連結的輸出,會让 JavaScript 在頁面加载後再把目标連結寫進 DOM。這種頁面用浏览器打開一切正常,点一下就跳走,但搜尋蜘蛛拿到的東西可能完全不一样。
先给结论
JS 動態生成的連結,搜尋蜘蛛有可能發現,但确定性遠不如直接寫在 HTML 里的 a 标簽。能不能發現,取决于蜘蛛是否會對這個頁面做渲染,以及渲染排期要等多久。對做 URL 發現来说,凡是停留在有可能,就意味着有相当一部分抓取會落空。
入口頁的目标是降低發現成本,而不是展示前端技術。連結出現在源碼里,是成本最低的做法。
搜尋蜘蛛讀頁面有两種模式
主流搜尋引擎處理一個 URL,大致分成两步:
- 抓取原始 HTML:先把服務器返回的那段源碼拿回来,這一步不执行 JS。連結不在源碼里,這一步就什么都拿不到。
- 渲染後再看一遍:把頁面放進渲染队列,用類似無头浏览器的方式执行 JS,再取一次 DOM。連結如果是這一步生成的,才有机會被看到。
問题在于第二步是有成本的。搜尋引擎不會對每個頁面都做完整渲染,渲染排期也要排队。頁面抓取频次低的时候,這一步可能迟迟不發生,甚至一直不發生。
哪几種寫法最容易漏
- 用 onclick 加 window.location 代替 a 标簽跳轉,源碼里根本没有連結。
- 把連結地址放在 JS 變量或接口返回的資料里,等异步請求回来再插入頁面。
- 整頁由前端框架渲染,首屏 HTML 里只有一個空容器。
- 先加载骨架屏,連結要等一两秒才出現。
- 渲染所需的脚本或样式文件本身被 robots.txt 挡住,渲染必然失敗。
反過来,如果只是用 JS 给已经存在的 a 标簽加埋点、改样式,連結本身還在源碼里,那基本不受影响。
想用 JS 又想稳妥,可以這样處理
- 把目标 URL 至少以 a 标簽加 href 的形式寫進服務端輸出的 HTML,JS 只做增强。
- 必须動態插入时,尽量在首屏同步插入,不要等异步接口,也不要等用戶交互。
- 確認渲染要用的 JS、CSS 文件没有被 robots.txt 拦掉。
- 控制一次抓取里要执行的脚本量,减少不必要的第三方资源。
- 重要入口頁尽量保持服務端渲染或静態輸出,JS 只作為补充手段。
怎么判断自己的頁面有没有被讀到
- 用浏览器查看網頁源代碼,注意不是审查元素,看能否直接搜到目标域名。搜不到,就是纯 JS 生成。
- 用搜尋引擎官方的 URL 检查類工具,對比原始 HTML 和渲染後 HTML 两種结果。
- 看服務器日誌,如果入口頁被频繁抓取,但目标站日誌里始终没有對應蜘蛛的记錄,多半就卡在渲染這一步。
- 做對照實驗:同样的連結,一份静態寫死、一份 JS 生成,分別放在两個入口頁,观察目标 URL 的抓取情况。
小结
JS 渲染不是不能用,但它把确定會被發現變成了可能會被發現。入口頁的作用是让目标 URL 尽快被看到,那就没必要在這里增加不确定性。能静態寫進源碼的連結,就不要交给 JavaScript。