用chrome headless+Puppeteer旁路渲染,解决单页的seo问题。

打算用vue等mvvm的框架做单页应用,seo是一个头疼的问题。虽然官方提供了服务端渲染的方案,总觉着那样就失去了客户端渲染的意义。

所以通过另一途径来解决spa单页应用的seo问题:通过一个旁路渲染服务,让爬虫过去,抓取渲染好的页面。

而这种渲染,完全是通过反代线上单页应用完成的。

这种方式的优点是简单、无需部署两套系统。

缺点就是速度有些堪忧,后续还要想办法优化一下。

关于是否被爬虫认定作弊的问题,还是有待探讨的(但毕竟返回的页面信息是一样的,也许不算作弊吧)

下面说一下架设过程。

本来打算用phantomjs来完成js页面的渲染。但是发现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代码,用来开启一个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代码,用来监听需要反代的网址。

插一句,这篇文章首发在简-书上面,怕被采集到其他平台上找不到来源,搞不懂的朋友可以来评论交流(搜索标题找)

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(); //创建一个页面.

        try {

            await page.goto(url); //到指定页面的网址.

            await page.waitFor(500);

        }

        catch (err) {

            await page.close();

            await browser.disconnect();

            console.log('出现错误:'+err); // 这里捕捉到错误 `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);

});


然后分别启动两个服务:node chrome.js 和node app.js 

这样,给你的nginx加一个UA验证,当时蜘蛛的时候,就反代到旁路渲染服务上去。

代码如下(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;

    }


至此,当爬虫访问你的SPA页的时候,返回的就是被渲染好,满满数据的页面了。

我是在nodejs的反代前面,又架设了一层nginx反代,好处是功能多,比如缓存,ip控制等。这里就不写出来了。

其实我感觉,速度上,好像chrome headless没有phantomjs的快,也许是第一次用phantomjs的时候,没有渲染完全的错觉。这个速度,也和要渲染的页面有关。看js多少。另外,在puppeteer配置方面,可以加快速度的方法,朋友们可以评论告知,不胜感激。

参考学习:

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

https://segmentfault.com/a/1190000011382062

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 162,158评论 4 370
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,600评论 1 307
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 111,785评论 0 254
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,655评论 0 220
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 53,075评论 3 295
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 41,002评论 1 225
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,146评论 2 318
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,918评论 0 211
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,671评论 1 250
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,838评论 2 254
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,318评论 1 265
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,636评论 3 263
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,343评论 3 244
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,187评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,982评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 36,126评论 2 285
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,934评论 2 279

推荐阅读更多精彩内容