用chrome headless+Puppeteer旁路渲染歼疮,解決單頁的seo問題杂抽。

打算用vue等mvvm的框架做單頁應(yīng)用,seo是一個(gè)頭疼的問題韩脏。雖然官方提供了服務(wù)端渲染的方案缩麸,總覺著那樣就失去了客戶端渲染的意義。

所以通過另一途徑來解決spa單頁應(yīng)用的seo問題:通過一個(gè)旁路渲染服務(wù)赡矢,讓爬蟲過去杭朱,抓取渲染好的頁面。

而這種渲染吹散,完全是通過反代線上單頁應(yīng)用完成的弧械。

這種方式的優(yōu)點(diǎn)是簡單、無需部署兩套系統(tǒng)空民。

缺點(diǎn)就是速度有些堪憂刃唐,后續(xù)還要想辦法優(yōu)化一下。

關(guān)于是否被爬蟲認(rèn)定作弊的問題界轩,還是有待探討的(但畢竟返回的頁面信息是一樣的画饥,也許不算作弊吧)

下面說一下架設(shè)過程。

本來打算用phantomjs來完成js頁面的渲染耸棒。但是發(fā)現(xiàn)vue用到的ES6特性荒澡,貌似無法完成,再加之chrome headless出來后与殃,phantomjs的作者宣布停止更新单山,所以索性就換一套方案,用chrome headless+Puppeteer幅疼。

chrome headless是谷歌退出的chrome瀏覽器的無頭版米奸,Puppeteer是谷歌官方出的一套基于nodejs的chrome headless API。

Puppeteer的API手冊(英文版):https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md

chrome.js代碼爽篷,用來開啟一個(gè)chrome瀏覽器悴晰。

// chrome.js

"use strict";

const puppeteer = require('puppeteer');

var fs = require("fs") ;

puppeteer.launch({dumpio:true,args: ['--no-sandbox', '--disable-setuid-sandbox'],timeout: 10000}).then(

? async browser => {

? fs.writeFile("chrome.txt",browser.wsEndpoint(),function (err) {

? ? if (err) throw err ;

? ? console.log("存入chrome.txt成功"); //文件被保存

? }) ;

? browser.disconnect()

});

app.js代碼,用來監(jiān)聽需要反代的網(wǎng)址逐工。

插一句铡溪,這篇文章首發(fā)在簡-書上面,怕被采集到其他平臺上找不到來源泪喊,搞不懂的朋友可以來評論交流(搜索標(biāo)題找)

const express = require('express');

const app = express();

const fs = require("fs");

const puppeteer = require('puppeteer');

const browserUrl = fs.readFileSync("chrome.txt","utf8");

app.get('*', function (req, res) {

? ? var url = req.protocol + '://'+ req.hostname + req.originalUrl;

? ? var ua = req.headers['user-agent'];

? ? (async() => {

? ? ? ? const browser = await puppeteer.connect({browserWSEndpoint:browserUrl});

? ? ? ? const page = await browser.newPage(); //創(chuàng)建一個(gè)頁面.

? ? ? ? try {

? ? ? ? ? ? await page.goto(url); //到指定頁面的網(wǎng)址.

? ? ? ? ? ? await page.waitFor(500);

? ? ? ? }

? ? ? ? catch (err) {

? ? ? ? ? ? await page.close();

? ? ? ? ? ? await browser.disconnect();

? ? ? ? ? ? console.log('出現(xiàn)錯(cuò)誤:'+err); // 這里捕捉到錯(cuò)誤 `error`

? ? ? ? }

? ? ? ? res.send(await page.content());? ? ? ?

? ? ? ? await page.close();

? ? ? ? await browser.disconnect();

? ? })();

});

var server = app.listen(3000,'127.0.0.1', function () {

? ? var host = server.address().address;

? ? var port = server.address().port;

? ? console.log('Example app listening at http://%s:%s', host, port);

});


然后分別啟動(dòng)兩個(gè)服務(wù):node chrome.js 和node app.js?

這樣棕硫,給你的nginx加一個(gè)UA驗(yàn)證,當(dāng)時(shí)蜘蛛的時(shí)候袒啼,就反代到旁路渲染服務(wù)上去哈扮。

代碼如下(nginx.conf):

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;

? ? ? ? proxy_set_header? X-Forwarded-Proto $scheme;

? ? ? ? if ($http_user_agent ~* "Baiduspider|twitterbot|facebookexternalhit|rogerbot|linkedinbot|embedly|quora link preview|showyoubot|outbrain|pinterest|slackbot|vkShare|W3C_Validator|bingbot|Sosospider|Sogou Pic Spider|Googlebot|360Spider") {

? ? ? ? ? ? proxy_pass? $scheme://127.0.0.1:3000;

? ? ? ? }

? ? ? ? index? index.html index.htm index.php;

? ? }


至此纬纪,當(dāng)爬蟲訪問你的SPA頁的時(shí)候,返回的就是被渲染好滑肉,滿滿數(shù)據(jù)的頁面了包各。

我是在nodejs的反代前面,又架設(shè)了一層nginx反代靶庙,好處是功能多问畅,比如緩存,ip控制等惶洲。這里就不寫出來了按声。

其實(shí)我感覺膳犹,速度上恬吕,好像chrome headless沒有phantomjs的快,也許是第一次用phantomjs的時(shí)候须床,沒有渲染完全的錯(cuò)覺铐料。這個(gè)速度,也和要渲染的頁面有關(guān)豺旬∧瞥停看js多少。另外族阅,在puppeteer配置方面篓跛,可以加快速度的方法,朋友們可以評論告知坦刀,不勝感激愧沟。

參考學(xué)習(xí):

http://www.r9it.com/20171106/puppeteer.html (中文api教程)

https://segmentfault.com/a/1190000011382062

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市鲤遥,隨后出現(xiàn)的幾起案子沐寺,更是在濱河造成了極大的恐慌,老刑警劉巖盖奈,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件混坞,死亡現(xiàn)場離奇詭異,居然都是意外死亡钢坦,警方通過查閱死者的電腦和手機(jī)究孕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來爹凹,“玉大人厨诸,你說我怎么就攤上這事」渫颍” “怎么了泳猬?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵批钠,是天一觀的道長。 經(jīng)常有香客問我得封,道長埋心,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任忙上,我火速辦了婚禮拷呆,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘疫粥。我一直安慰自己茬斧,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布梗逮。 她就那樣靜靜地躺著项秉,像睡著了一般。 火紅的嫁衣襯著肌膚如雪慷彤。 梳的紋絲不亂的頭發(fā)上娄蔼,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天,我揣著相機(jī)與錄音底哗,去河邊找鬼岁诉。 笑死,一個(gè)胖子當(dāng)著我的面吹牛跋选,可吹牛的內(nèi)容都是我干的涕癣。 我是一名探鬼主播,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼前标,長吁一口氣:“原來是場噩夢啊……” “哼坠韩!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起候生,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤同眯,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后唯鸭,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體须蜗,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年目溉,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了明肮。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,690評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡缭付,死狀恐怖柿估,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情陷猫,我是刑警寧澤秫舌,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布的妖,位于F島的核電站,受9級特大地震影響足陨,放射性物質(zhì)發(fā)生泄漏嫂粟。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一墨缘、第九天 我趴在偏房一處隱蔽的房頂上張望星虹。 院中可真熱鬧,春花似錦镊讼、人聲如沸宽涌。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽卸亮。三九已至,卻和暖如春嚼松,著一層夾襖步出監(jiān)牢的瞬間嫡良,已是汗流浹背锰扶。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工献酗, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人坷牛。 一個(gè)月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓罕偎,卻偏偏與公主長得像,于是被迫代替她去往敵國和親京闰。 傳聞我的和親對象是個(gè)殘疾皇子颜及,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評論 2 353

推薦閱讀更多精彩內(nèi)容