先擼擼幾個概念:html
總體仍是結合當前需求的場景 和自身的條件來進行選擇,短期高效完成需求。前端
相關收錄文章:vue
Nuxt Next Prerender + vuejs SEO最佳實踐 百度爬蟲 + 谷歌收錄 親測成功Prerender.io 前端渲染與 SEO 優化踩坑 小記 用PhantomJS來給AJAX站點作SEO優化 ####一個PhantomJS任務腳本 首先,咱們須要一個叫spider.js的文件,用於phantomjs 解析網站。node
"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/'
linux
響應搜索引擎爬蟲的請求,咱們須要將此命令服務化,經過node起個簡單的web服務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配置,咱們能夠輕鬆的解決這個問題。express
# 定義一個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;
}
}
複製代碼
參考連接:緩存
www.mxgw.info/t/phantomjs… imweb.io/topic/560b4… icewing.cc/linux-insta… www.jianshu.com/p/2bbbc2fcd…服務器