基于谷歌/火狐无头浏览器模式解决Vue的SEO问题
基于谷歌/火狐无头浏览器模式解决Vue的SEO问题
启发来自冷子欲的文章: 基于Vue SEO的四种方案,感谢作者的分享。
在他的文章里【使用Phantomjs针对爬虫做处理】对于已经开发完成的单页面Vue项目是很好的选择,但是我用Phantomjs安装完后不能正常工作,另外“PhantomJS宣布终止开发”,所以选择弃用Phantomjs转用其他的方案代替。
Phantomjs的本质是一个无头浏览器,我了解到谷歌和火狐都有无头浏览器模式,所以想到使用python调用浏览器来实现返回渲染好的html页面。
下面是我设计的流程图

下面是具体的流程,在流程开始之前要安装Nginx、火狐/谷歌、Nodejs、python环境,安装及使用这里就不赘述了:
1.Nginx做转发
在Nginx的配置文件里的http区块加转发地址:
1 2 3
| upstream spider_server { server localhost:3000; }
|
在http区块->server区块->location区块里加判断:
1 2 3
| 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 http://spider_server; }
|
这样便实现了对百度或其余的爬虫转发到3000端口,3000端口是node.js程序监听的地址,可以自己设置。
2.使用node.js调用python爬虫
创建server.js文件并运行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
| var express = require('express'); var app = express();
var child_process = require('child_process'); var iconv = require('iconv-lite');
app.get('*', function(req, res) { res.writeHead(200, {'Content-Type': 'text/html; charset=utf-8'}); var url = req.protocol + '://'+ req.hostname + req.originalUrl;
var content = '';
var firefox = child_process.spawn('python', ['firefox.py', url]);
firefox.stdout.on('data', function(data){ content += iconv.decode(new Buffer(data, 'binary'), 'gb2312'); });
firefox.stderr.on('data', function (data) { console.log('standard error output:\n' + data); });
firefox.on('exit', function(code){ switch (code){ case 1: console.log('load error'); res.write('加载失败'); break; case 2: console.log('timeout: '+ url); res.write('time out'); break; default: res.write(content); break; } res.end(); });
});
app.listen(3000, function () { console.log('Spider app listening on port 3000!'); });
|
这里的3000便是Nginx转发的端口。
3.使用python调用谷歌/火狐浏览器获得渲染数据
这里使用python调用火狐浏览器获取渲染数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| from selenium.webdriver.firefox.options import Options from selenium import webdriver import sys
js_delStyle = "var elems = document.getElementsByTagName('style');" \ "for(var i = 0; i < elems.length; i++){elems[i].parentNode.removeChild(elems[i]);}"
options = Options() options.add_argument('--headless') options.set_preference('permissions.default.image', 2) browser = webdriver.Firefox(options=options) browser.get(url=sys.argv[1]) browser.execute_script(js_delStyle) print(browser.page_source.encode('GBK','ignore').decode('GBk')) browser.close() browser.quit()
|
可以看到使用了无头、无界面、不加载图片的浏览器模式,并且请求后对html做了处理,删除了不必要的