上一篇博文(http://www.cnblogs.com/ideal-lx/p/5625428.html)介紹了單頁(yè)面搜索引擎優(yōu)化的原理,以及介紹了兩個(gè)開源框架的優(yōu)劣。prerender框架的工作原理在上篇也有介紹,本片博文主要介紹prerender.io的部署實(shí)踐過(guò)程。其實(shí)部署的過(guò)程還是比較簡(jiǎn)單的,閱讀原網(wǎng)站可以直接移步:https://github.com/prerender/prerender。
一、支持google優(yōu)化方案
上篇文也有提到,谷歌提出了自己的一套針對(duì)ajax頁(yè)面的抓取方案,prerender在這里同樣對(duì)其做了支持。使用起來(lái)很簡(jiǎn)單:
1、添加<meta name="fragment" content="!">標(biāo)簽在每個(gè)主頁(yè)面的header內(nèi)。
2、如果url中含有#,將它們變成#!(hash-bang)的形式.
關(guān)于上面第二點(diǎn),angular的api $locationProvider.hashPrefix('!');即可使url變成hash-bang形式。
二、prerender.io服務(wù)端部署
prerender官方提供了云服務(wù),獲取tocken后便可以配置使用。不過(guò)我們這里不想使用官方的服務(wù),選擇自己搭建自己的可控prerender服務(wù),當(dāng)然,最好使用linux機(jī)器作為服務(wù)器。過(guò)程也非常簡(jiǎn)單,上篇介紹,prerender服務(wù)是一個(gè)持續(xù)在跑的node服務(wù),負(fù)責(zé)接收client轉(zhuǎn)發(fā)過(guò)來(lái)的請(qǐng)求,然后再請(qǐng)求web服務(wù),獲得html、js等靜態(tài)文件后執(zhí)行并繼續(xù)請(qǐng)求后續(xù)ajax請(qǐng)求。首先要在服務(wù)器上安裝node運(yùn)行環(huán)境,執(zhí)行以下步驟即可安裝部署prerender服務(wù):
$ git clone https://github.com/prerender/prerender.git
$ cd prerender
$ npm install
$ node server.js
過(guò)程中會(huì)安裝phantomjs,最后一步“node server.js”便啟動(dòng)了prerender服務(wù)。我們先來(lái)看一看源碼的目錄:
http://localhost:3000/http://www.yourwebsite.com
看到這里就清楚了,其實(shí)就是把咱們頁(yè)面的url當(dāng)做參數(shù)傳給prernder服務(wù),就可以了。如果是在另外的主機(jī),同樣可以訪問(wèn) http://prerender服務(wù)的地址:監(jiān)聽端口號(hào)/需要渲染的頁(yè)面url,即可看到通過(guò)prerender.io渲染后的頁(yè)面。如果有條件的話可以通過(guò)本地爬蟲訪問(wèn)此url,你會(huì)發(fā)現(xiàn)所有的動(dòng)態(tài)數(shù)據(jù)也可以同樣得到。三、prerender.io客戶端部署
prerender提供了非常豐富的客戶端實(shí)現(xiàn)方案,包括node、Ruby、Apache、Nginx、Java、Go、Grails等等官方非官方方案,上面git的連接即可以查到各個(gè)方案的部署方式。筆者的應(yīng)用是前后端分離使用nginx做靜態(tài)資源容器的環(huán)境,這里介紹一下nginx的部署方案,以下是官方提供的nginx.conf 的配置文件:
server { | |
listen 80; | |
server_name example.com; | |
root /path/to/your/root; | |
index index.html; | |
location / { | |
try_files $uri @prerender; | |
} | |
location @prerender { | |
set $prerender 0; | |
if ($http_user_agent ~* "baiduspider|twitterbot|facebookexternalhit|rogerbot|linkedinbot|embedly|quora link preview|showyoubot|outbrain|pinterest|slackbot|vkShare|W3C_Validator") { | |
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)") { | |
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 "192.168.1.168:3000*"; | |
rewrite .* /$scheme://$host$request_uri? break; | |
proxy_pass http://$prerender; | |
} | |
if ($prerender = 0) { | |
rewrite .* /index.html break; | |
} | |
} | |
} |
下面對(duì)相關(guān)參數(shù)做簡(jiǎn)單介紹:
listen:監(jiān)聽端口號(hào),根據(jù)項(xiàng)目實(shí)際情況而定。
server_name:監(jiān)聽的域名。
root :默認(rèn)首頁(yè)的路徑。
index:默認(rèn)的首頁(yè)頁(yè)面。
location @prerender 下依次是對(duì):userAgent的配置、可根據(jù)需要自行添加;_escaped_fragment_符號(hào)的過(guò)濾;prerender自己爬蟲請(qǐng)求的排除;不需要抓取的文件類型配置,可自行添加。
然后下面 如果$prerender 變量為1,就把請(qǐng)求定向到prerender服務(wù)所在的地址。
四、緩存的設(shè)置
prerender提供了豐富的緩存機(jī)制,用來(lái)存儲(chǔ)已抓取的頁(yè)面,當(dāng)下次同樣的頁(yè)面抓取請(qǐng)求再來(lái)的時(shí)候prerender便可以命中緩存返回給爬蟲。筆者使用的是levelDB的緩存,安裝可查看https://github.com/maxlath/prerender-level-cache,需要安裝一個(gè)node外殼的levelDB數(shù)據(jù)庫(kù),供prerender服務(wù)插件調(diào)用。插件的啟用方法,就是在server.js里server.use(require('prerender-level-cache'));
即可。
另外在生產(chǎn)環(huán)境測(cè)試的時(shí)候,筆者遇到一個(gè)問(wèn)題,就是pererender服務(wù)跑了一段時(shí)間之后,爬蟲過(guò)來(lái)的請(qǐng)求有些會(huì)返回304狀態(tài)碼回去,這樣的話爬蟲是收不到頁(yè)面數(shù)據(jù)的。304是http協(xié)議做緩存控制的狀態(tài)碼,返回304意味著服務(wù)端認(rèn)為請(qǐng)求方擁有最新的緩存。我解決這個(gè)問(wèn)題的方式是又開啟了一次phantomjs的本地緩存,在prerender服務(wù)的lib\server.js里server.createPhantom方法內(nèi)將phantomjs的啟動(dòng)參數(shù)改為:var args = {'--load-images': false, '--ignore-ssl-errors': true, '--ssl-protocol': 'tlsv1.2','--disk-cache':true}; 這個(gè)問(wèn)題便沒有再出現(xiàn)。
聯(lián)系客服