使用Prerender.io進行網站預載入

請叫我胖子發表於2019-08-14

我在自己的專案中是採用的前後端分離的技術,前端用的VUE開發,後端是JAVA開發,tomcat部署,nginx轉發,但是VUE開發的專案缺點就是不利於SEO,所以針對SEO做了預載入的操作。

決定採用Prerender.io進行預載入,好處就是不用區分前端是VUE開發的還是Angular等其它前端技術開發的都能統一做預載入,因為他的原理就是針對Spider爬蟲程式(通過user-agent進行區分,然後用nginx進行轉發),會先用google-chrome載入網站資源,再把載入完成的程式碼返回給爬蟲程式;同時nginx轉發時察覺是非Spdier爬蟲來源時就不用google-chrome進行載入後再返回,而是直接訪問原網站,因為這樣勢必會加大處理時長,影響使用者訪問體驗。

使用Prerender.io主體上我是參考了下面這篇文章進行的,但是在過程中以及一些配置上有改動,且會做一些補充以及我額外遇到的坑的解決方案:
https://blog.csdn.net/zai_xia/article/details/86697300

1、首先註冊登入 Prerender.io,並且獲得個人token(需*學上網註冊)
2、配置Nginx中介軟體,下面是我的配置。重點說下這裡遇到的坑,就是下面標紅的那塊程式碼,一定要去掉

# For more information on configuration, see:
#   * Official English Documentation: http://nginx.org/en/docs/
#   * Official Russian Documentation: http://nginx.org/ru/docs/

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

# Load dynamic modules. See /usr/share/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;

events {
    worker_connections 1024;
}

http {
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 2048;

    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;

    # Load modular configuration files from the /etc/nginx/conf.d directory.
    # See http://nginx.org/en/docs/ngx_core_module.html#include
    # for more information.
    include /etc/nginx/conf.d/*.conf;

    server {
        listen       80;#預設埠是80,如果埠沒被佔用可以不用修改
        server_name  www.*****.com ****.com;
        root        /opt/coinUnitWebH5/dist;#vue專案的打包後的dist
        index index.html;
        location / {
            #try_files $uri $uri/ @prerender;#需要指向下面的@否則會出現vue的路由在nginx中重新整理出現404
            try_files $uri @prerender;
	    index  index.html index.htm;
        }
        #對應上面的@,主要原因是路由的路徑資源並不是一個真實的路徑,所以無法找到具體的檔案
        #因此需要rewrite到index.html中,然後交給路由在處理請求資源
	location @prerender {
        	proxy_set_header X-Prerender-Token 官網上註冊得到的token;
        	set $prerender 0;
        	if ($http_user_agent ~* "googlebot|bingbot|yandex|baiduspider|twitterbot|facebookexternalhit|rogerbot|linkedinbot|embedly|quora link preview|showyoubot|outbrain|pinterest\/0\.|pinterestbot|slackbot|vkShare|W3C_Validator|whatsapp") {
           		set $prerender 1;
       		}
        	if ($args ~ "_escaped_fragment_") {
            		set $prerender 1;
        	}
        	if ($http_user_agent ~ "Prerender") {
            		set $prerender 0;
        	}
       		if ($uri ~* "\.(js|css|xml|less|png|jpg|jpeg|gif|pdf|doc|txt|ico|rss|zip|mp3|rar|exe|wmv|doc|avi|ppt|mpg|mpeg|tif|wav|mov|psd|ai|xls|mp4|m4a|swf|dat|dmg|iso|flv|m4v|torrent|ttf|woff|svg|eot)") {
            		set $prerender 0;
        	}
        	#resolve using Google's DNS server to force DNS resolution and prevent caching of IPs
        	resolver  8.8.8.8;
        	if ($prerender = 1) {
            		#setting prerender as a variable forces DNS resolution since nginx caches IPs and doesnt play well with load balancing
            		#set $prerender "service.prerender.io";
            		set $prerender "127.0.0.1:3000";
			rewrite .* /$scheme://$host$request_uri? break;
            		proxy_pass http://$prerender;
        	}
        	if ($prerender = 0) {
            		#rewrite .* /index.html break;
			rewrite ^.*$ /index.html last;
        	}
    	}
    }
}

3、檢查nginx並重啟

nginx -t
service nginx restart

4、下載prerender服務安裝在本地

git clone https://github.com/prerender/prerender.git

若沒有安裝git服務,可手動從Github下載再上傳到/usr資料夾下,再解壓到當前目錄下

5、安裝npm依賴

cd /usr/prerender

# Phantomjs 官方的下載地址會超時,此處重新指定其下載地址為淘寶映象
export PHANTOMJS_CDNURL=https://npm.taobao.org/mirrors/phantomjs

npm install

文件結構如下:

6、執行server.js

# 啟動Server.js, 預設監聽3000埠
node server.js

備註:

可用netstat -lntp命令檢視是否有3000埠,想重啟服務需要先用ps -ef | grep node檢視pid後kill掉再啟動

啟動時,如果預先沒有安裝過Chrome,則會啟動失敗,提示啟動Chrome失敗,未檢測到Chrome,此時安裝Chrome就好了,為什麼要安裝Chrome呢,因為Prerender並不負責真正的網頁解析,Prerender只負責解析前後的處理,實際是由Chrome負責網頁的解析。

7、安裝Chrome:

  7.1、配置yum源

  因為國內無法訪問Google,所以需要自己配置yum源,在目錄 /etc/yum.repos.d/ 下新建google-chrome.repo檔案

cd /ect/yum.repos.d/

touch google-chrome.repo

  7.2、寫入內容

vi google-chrome.repo

[google-chrome]
name=google-chrome
baseurl=http://dl.google.com/linux/chrome/rpm/stable/$basearch
enabled=1
gpgcheck=1
gpgkey=https://dl-ssl.google.com/linux/linux_signing_key.pub

  7.3、安裝執行

# 國內推薦
yum -y install google-chrome-stable --nogpgcheck

  7.4、安裝路徑

  安裝成功後,Chrome的安裝路徑應該是
  /opt/google/chrome

  預設情況下,root使用者不能直接執行chrome,所以可以新建另一個使用者如other來執行

cd /opt/google/chrome

su other

./chrome

  備註:

  這裡我執行./chrome的時候會提示“Gtk-WARNING **: cannot open display”,網上說需要新建的使用者來執行,可是我新建了使用者執行還是不行,於是又寫換到root使用者,執行“xhost +”命令,用處是讓圖形化介面能在所有使用者上都能展示。可是執行“xhost +”是又遇到新問題,提示“  unable to open display ""  ”,簡直了!,然後各種嘗試,用root執行“  執行export DISPLAY=:127.0.0.1.0 ”,不行!於是安裝 vncserver ,如何安裝就不累述了,網上一大堆,需要注意的是,執行vncserver命令的時候,如果遇到執行了,沒有異常問題,但是檢視程式就是沒有這個程式的時候,一定要看執行命令是列印的log日誌,我的情況是在log日誌裡面最後面一行有一個Kill,每次啟動後自動kill掉了,於是根據日誌找到啟動指令碼檔案編輯把最後一行的Kill命令去掉了就行了。

  經過上面的操作後,再執行xhost +成功,然後用新使用者執行./chrome不成功,還是要用root使用者執行才行,就沒有繼續深究

  7.5、以守護程式執行chrome

vim /opt/google/chrome/google-chrome

 

  將最後一行修改為:

exec -a "$0" "$HERE/chrome" "$@" --user-data-dir --no-sandbox

 

8、啟動Prerender.oi服務

  執行

su other

cd /usr/prerender

node ./server.js

  看到以下則啟動成功

  以守護程式啟動:nohup node ./server.js &

9、檢查各種程式是否啟動成功

  用命令“netstat -lntp”檢視得到如下:

  都已啟動!

10、用curl測試預載入是否生效

  先用curl http://www.******.com 檢視是得到未渲染的原始碼

  用本地prerender.io服務代理驗證curl http://localhost:3000/http://www.*******.com 正常得到的應該是渲染之後的程式碼,也就是谷歌瀏覽器載入後的。

  再驗證nginx攔截轉發是否正常,模擬爬蟲curl --user-agent "baiduspider" http://www.******.com 得到的也是代理後的結果,一切OK!

相關文章