vue无需改动代码的SEO优化–puppeteer(详细流程)
目录
- vue无需改动代码的SEO优化--puppeteer(详细流程)
- 一级目录
- 二级目录
- 三级目录
- 一、安装puppeteer:npm install puppeteer --save
- 安装依赖
- 二、编写puppeteer服务js文件
- puppeteer-pool.js 性能优化,去除不必要的功能,提高性能。
- spider.js渲染请求的页面
- server.js,通过express 开启一个服务器。接受转发的请求
- nginx配置
- 三、测试puppeteer配置
一级目录
二级目录
三级目录
Puppeteer 是一个node库,他提供了一组用来操纵Chrome的API, 通俗来说就是一个 headless chrome浏览器 (当然你也可以配置成有UI的,默认是没有的)。既然是浏览器,那么我们手工可以在浏览器上做的事情 Puppeteer 都能胜任, 另外,Puppeteer 翻译成中文是”木偶”意思,你可以很方便的操纵她去实现:
1) 生成网页截图或者 PDF
2) 高级爬虫,可以爬取大量异步渲染内容的网页
3) 模拟键盘输入、表单自动提交、登录网页等,实现 UI 自动化测试
4) 捕获站点的时间线,以便追踪你的网站,帮助分析网站性能问题
SEO优化,主要是为了解决百度收录问题,实现原理就是我们首先去访问nginx,nginx转发到puppeteer服务,由puppeteer服务模拟浏览器请求获取数据,然后返回到页面。这样可以达成直接返回html的效果了。如下图:
一、安装puppeteer:npm install puppeteer --save
npm install puppeteer --save
执行完会后会再当前目录下载一个node_modules文件夹,在执行命令时可以切换到自己想要下载的目录下载,如:cd /uer/local/ 之后再执行npm install 的命令
安装依赖
# 依赖库
yum install pango.x86_64 libXcomposite.x86_64 libXcursor.x86_64 libXdamage.x86_64 libXext.x86_64 libXi.x86_64 libXtst.x86_64 cups-libs.x86_64 libXScrnSaver.x86_64 libXrandr.x86_64 GConf2.x86_64 alsa-lib.x86_64 atk.x86_64 gtk3.x86_64 -y
# 字体
yum install ipa-gothic-fonts xorg-x11-fonts-100dpi xorg-x11-fonts-75dpi xorg-x11-utils xorg-x11-fonts-cyrillic xorg-x11-fonts-Type1 xorg-x11-fonts-misc -y
在安装完这些依赖后 我在启动下面的js时还是提示缺少库。如果不缺少可以跳过这里。(检查凡是就是执行下面的js是否报错)
如:在调用chrome的时候缺少libdrm.so.2库
error while loading shared libraries: libdrm.so.2: cannot open shared object file:
可以执行如下命令查看还缺那些库 ,cd后面是路径 一般报错里会有自己的路径。
cd /xxx/xxx/puppeteer/chrome/linux-xxx/chrome-linux/
ldd chrome
执行完 ldd chrome命令
结果如下:
linux-vdso.so.1 => (0x00007fffd5fb6000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x000000379e200000)
libcrypt.so.1 => /lib64/libcrypt.so.1 (0x000000393f200000)
libpcre.so.0 => /lib64/libpcre.so.0 (0x00000033d5800000)
libssl.so.10 => /usr/lib64/libssl.so.10 (0x0000003c60200000)
libcrypto.so.10 => /usr/lib64/libcrypto.so.10 (0x0000003df9800000)
libdl.so.2 => /lib64/libdl.so.2 (0x000000390be00000)
libz.so.1 => /lib64/libz.so.1 (0x0000003a25600000)
libc.so.6 => /lib64/libc.so.6 (0x0000003a24200000)
libdrm.so.2 => not found
/lib64/ld-linux-x86-64.so.2 (0x0000003a23e00000)
libfreebl3.so => /lib64/libfreebl3.so (0x000000393ea00000)
libgssapi_krb5.so.2 => /lib64/libgssapi_krb5.so.2 (0x000000379fa00000)
libkrb5.so.3 => /lib64/libkrb5.so.3 (0x000000379d200000)
libcom_err.so.2 => /lib64/libcom_err.so.2 (0x000000379e600000)
libk5crypto.so.3 => /lib64/libk5crypto.so.3 (0x0000003df9c00000)
…………
可以看出来缺少的库的名字和是否缺少其他库【libdrm.so.2 => not found 】
找到缺少的库之后只需要执行yum install 库名就可以了:
yum install libdrm*
将下面这段代码保存为 index.js ,然后运行 node index.js 就可以在根目录下得到一个 example.png 的截图。(用于验证puppeteer是否安装成功)
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({
args: [
'--no-sandbox',
'--disable-setuid-sandbox',
]
});
const page = await browser.newPage();
await page.goto('https://www.baidu.com');
await page.screenshot({path: 'example.png'});
await browser.close();
})();
二、编写puppeteer服务js文件
可以先新建一个目录如:puppeteer_project
mkdir puppeteer_project
文件目录结构
**注意:**文件名最后不要随意改,因为相互之间有引用,要改文件名其他引用这个文件的地方也需要改。
puppeteer_project
–puppeteer-pool.js
–spider.js
–service.js
puppeteer-pool.js 性能优化,去除不必要的功能,提高性能。
const puppeteer = require('puppeteer')
const MAX_WSE = 2; //启动几个浏览器
let WSE_LIST = []; //存储browserWSEndpoint列表
//负载均衡
(async () => {
for (var i = 0; i < MAX_WSE; i++) {
const browser = await puppeteer.launch({
//无头模式
headless: true,
//参数
args: [
'--disable-gpu',
'--disable-dev-shm-usage',
'--disable-setuid-sandbox',
'--no-first-run',
'--no-sandbox',
'--no-zygote',
'--single-process'
]
});
browserWSEndpoint = await browser.wsEndpoint();
WSE_LIST.push(browserWSEndpoint);
}
})();
module.exports = WSE_LIST
spider.js渲染请求的页面
const puppeteer = require('puppeteer')
const WSE_LIST = require('./puppeteer-pool.js')
const spider = async (url) => {
let tmp = Math.floor(Math.random() * WSE_LIST.length);
//随机获取浏览器
let browserWSEndpoint = WSE_LIST[tmp];
//连接
const browser = await puppeteer.connect({
browserWSEndpoint
});
//打开一个标签页
var page = await browser.newPage();
//打开网页
await page.goto(url, {
timeout: 0, //连接超时时间,单位ms
waitUntil: 'networkidle0' //网络空闲说明已加载完毕
})
//获取渲染好的页面源码。不建议使用await page.content();获取页面,因为在我测试中发现,页面还没有完全加载。就获取到了。页面源码不完整。也就是动态路由没有加载。vue路由也配置了history模式
var html = await page.evaluate(() => {
return document.getElementsByTagName('html')[0].outerHTML;
});
await page.close();
return html;
}
module.exports = spider;
server.js,通过express 开启一个服务器。接受转发的请求
var express = require('express');
var app = express();
var spider = require("./spider.js")
var minify = require('html-minifier').minify;
app.get('*', async (req, res, next) => {
// 部署到服务器的完整URL
var url = req.protocol + '://'+ req.hostname + req.originalUrl;
console.log('请求的完整URL:' + url);
var content = await spider(url).catch((error) => {
console.log(error);
res.send('获取html内容失败');
return;
});
//由于是直接获取的源码,下面通过minify库压缩代码,也不知道是不是多余的。
content=minify(content,{removeComments: true,collapseWhitespace: true,minifyJS:true, minifyCSS:true});
res.send(content);
});
//监听4000端口
app.listen(4000, () => {
console.log('预渲染服务已启动!');
});
引用js的下载,要不然可能找不到方法【 code: ‘MODULE_NOT_FOUND’,】
npm install express --save
npm install html-minifier --save
执行启动puppeteer命令
node server.js
或
node server.js &
后面带&的是后台运行,不带&的启动命令可以用来看日志,访问的链接会打印出来。
相当与启动了一个端口为4000的puppeteer服务。
启动的时候可能端口占用 4000被占用的话就换一个其他端口。
nginx配置
server {
listen 80;
server_name xxx.com localhost;
location / {
# 蜘蛛爬虫处理
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
if ($http_user_agent ~* "spider|bot") {
proxy_pass http://localhost:4000;
}
try_files $uri $uri/ @router;
}
location @router {
rewrite ^(.*)$ /index.html last;
}
}
修改完nginx conf文件之后可以执行
nginx -t
检查配置是否格式正确,正确的话结果如下 最后有successful
nginx: the configuration file /xxx/xxx/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /xxx/xxx/nginx/conf/nginx.conf test is successful
之后再执行重启nginx即可。
nginx -s reload
注意
三、测试puppeteer配置
可以使用postman调用接口测试
headers里要加配置模仿爬虫参数。
User-Agent:spider
刚刚启动puppeteer(service.js)的时候访问可能比较慢,大几秒左右,启动半分钟左右再调用就会快一些,大概3秒能返回数据。具体访问速度可能可以不同服务器有关。
测试日志如下: