動態網站SEO解決方案經驗彙總

動態網站 SEO解決方案彙總

先擼擼幾個概念:

  • SPA:單頁面應用,基於vue框架開發的項目很多都屬於單頁面應用。
  • SSR :server side rendering, 服務端渲染。
  • SEO:搜索引擎優化,指通過對網站進行站內優化、修復和站外優化,從而提高網站的網站關鍵詞排名以及公司產品的曝光度。
  • Prerender:預渲染,Prerender.io是基於Node.js的程序,它可以讓你的JavaScript網站支持搜索引擎,社交媒體,並且它兼容所有的JavaScript框架和庫。它採用PhantomJS渲染JavaScript的網頁然後呈現爲HTML。此外,我們可以實現的prerender服務層來緩存訪問過的頁面,這將大大提高性能。(省事兒)
  • Nuxt:是一個基於 Vue.js 的通用應用框架,預設了利用Vue.js開發服務端渲染的應用所需要的各種配置,可以爲基於 Vue.js 的應用提供生成對應的靜態站點的功能。
  • Next:對標的是 React的通用應用框架,預設了React.js 開發服務端渲染的應用所需要的各種配置。

技術選型

  • 結合現有項目框架選用,時間成本,學習成本進行合適的評估
  • 從自身能力出發 如果涉及太多的服務端處理的東西 可以考慮運維層進行處理採用prerender
  • 業務應用場景,業務線比較複雜工期較短的時候 建議自己進行PrerenderIo 的部署,使用自己的服務器進行對爬蟲頁面進行緩存。

三個技術選型優劣對比

  • Next => React 文檔大部分是英文的 配置項簡單易上手,部署方便,大型的官網項目比較適合,用戶交互複雜的時候採用Next 進行項目開發。
  • Nuxt => Vue 基本是Next的翻版,語法也是Next語法,大坑的地方是在 大多數穩定的項目是1.4.2的版本 現有2.X的版本 基本完全不兼容老版本。

    • 渲染效率比較低,業務複雜的時候 編譯速度十分慢。十分慢
    • 版本跨度大的適合兼容性低。
  • PhantomJS 原理就是通過Nginx配置,將搜索引擎的爬蟲請求轉發到一個node server,再通過PhantomJS來解析完整的HTML。

    • 可以做爲一整套通用服務,所有的SPA頁面基本不需要二次重構。
    • 缺點是受網絡波動制約性比較強,
    • 適合複雜項目短時間進行收錄處理
    • 需要網絡層的權限 需要和運維進行溝通。

整體還是結合當前需求的場景 和自身的條件來進行選擇,短時間高效完成需求。

相關收錄文章:

Nuxt
Next
Prerender + vuejs SEO最佳實踐 百度爬蟲 + 谷歌收錄 親測成功Prerender.io
前端渲染與 SEO 優化踩坑 小記
用PhantomJS來給AJAX站點做SEO優化

一個PhantomJS任務腳本

首先,我們需要一個叫spider.js的文件,用於phantomjs 解析網站。

"use strict";

// 單個資源等待時間,避免資源加載後還需要加載其他資源
var resourceWait = 500;
var resourceWaitTimer;
// 最大等待時間
var maxWait = 5000;
var maxWaitTimer;
// 資源計數
var resourceCount = 0;
// PhantomJS WebPage模塊
var page = require('webpage').create();
// NodeJS 系統模塊
var system = require('system');
// 從CLI中獲取第二個參數爲目標URL
var url = system.args[1];
// 設置PhantomJS視窗大小
page.viewportSize = {
    width: 1280,
    height: 1014
};
// 獲取鏡像
var capture = function(errCode){
    // 外部通過stdout獲取頁面內容
    console.log(page.content);
    // 清除計時器
    clearTimeout(maxWaitTimer);
    // 任務完成,正常退出
    phantom.exit(errCode);
};
// 資源請求並計數
page.onResourceRequested = function(req){
    resourceCount++;
    clearTimeout(resourceWaitTimer);
};
// 資源加載完畢
page.onResourceReceived = function (res) {
    // chunk模式的HTTP回包,會多次觸發resourceReceived事件,需要判斷資源是否已經end
    if (res.stage !== 'end'){
        return;
    }
    resourceCount--;
    if (resourceCount === 0){
        // 當頁面中全部資源都加載完畢後,截取當前渲染出來的html
        // 由於onResourceReceived在資源加載完畢就立即被調用了,我們需要給一些時間讓JS跑解析任務
        // 這裏默認預留500毫秒
        resourceWaitTimer = setTimeout(capture, resourceWait);
    }
};
// 資源加載超時
page.onResourceTimeout = function(req){
    resouceCount--;
};
// 資源加載失敗
page.onResourceError = function(err){
    resourceCount--;
};
// 打開頁面
page.open(url, function (status) {
    if (status !== 'success') {
        phantom.exit(1);
    } else {
        // 當改頁面的初始html返回成功後,開啓定時器
        // 當到達最大時間(默認5秒)的時候,截取那一時刻渲染出來的html
        maxWaitTimer = setTimeout(function(){
            capture(2);
        }, maxWait);
    }
});

進行測試=> phantomjs spider.js 'https://www.baidu.com/'

命令服務化

響應搜索引擎爬蟲的請求,我們需要將此命令服務化,通過node起個簡單的web服務

var express = require('express');
var app = express();
// 引入NodeJS的子進程模塊
var child_process = require('child_process');
app.get('/', function(req, res){
    // 完整URL
    var url = req.protocol + '://'+ req.hostname + req.originalUrl;
    console.log(req,req.hostname)
    // 預渲染後的頁面字符串容器
    var content = '';
    // 開啓一個phantomjs子進程
    var phantom = child_process.spawn('phantomjs', ['spider.js', url]);
    
    // 設置stdout字符編碼
    phantom.stdout.setEncoding('utf8');
    // 監聽phantomjs的stdout,並拼接起來
    phantom.stdout.on('data', function(data){
        content += data.toString();
    });
    // 監聽子進程退出事件
    phantom.on('exit', function(code){
        switch (code){
            case 1:
                console.log('加載失敗');
                res.send('加載失敗');
                break;
            case 2:
                console.log('加載超時: '+ url);
                res.send(content);
                break;
            default:
                res.send(content);
                break;
        }
    });
    
});
app.listen(3002)

運行node server.js,此時我們已經有了一個預渲染的web服務啦,接下來的工作便是將搜索引擎爬蟲的請求轉發到這個web服務,最終將渲染結果返回給爬蟲。
爲了防止node進程掛掉,可以使用nohup來啓動,nohup node server.js &。
通過Nginx配置,我們可以輕鬆的解決這個問題。

# 定義一個Nginx的upstream爲spider_server
upstream spider_server {
  server localhost:3000;
}
# 指定一個範圍,默認 / 表示全部請求
location / {
  proxy_set_header  Host            $host:$proxy_port;
  proxy_set_header  X-Real-IP       $remote_addr;
  proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
  # 當UA裏面含有Baiduspider的時候,同時可以加其他的頭信息進行轉發 流量Nginx以反向代理的形式,將流量傳遞給spider_server
  if ($http_user_agent ~* "Baiduspider") {
    proxy_pass  http://spider_server;
  }
}
參考鏈接:
https://www.mxgw.info/t/phant...
http://imweb.io/topic/560b402...
https://icewing.cc/linux-inst...
https://www.jianshu.com/p/2bb...
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章