• vue无需改动代码的SEO【百度爬取】优化--puppeteer(详细流程)


    vue无需改动代码的SEO优化–puppeteer(详细流程)

    概念

    Puppeteer 是一个node库,他提供了一组用来操纵Chrome的API, 通俗来说就是一个 headless chrome浏览器 (当然你也可以配置成有UI的,默认是没有的)。

    SEO优化,主要是为了解决百度收录问题,实现原理就是我们首先去访问nginx,nginx转发到puppeteer服务,由puppeteer服务模拟浏览器请求获取数据,然后返回到页面。这样可以达成直接返回html的效果了。如下图:

    puppeteer服务调用流程

    一、安装puppeteer:npm install puppeteer --save

    npm install puppeteer --save
    
    • 1

    执行完会后会再当前目录下载一个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
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    将下面这段代码保存为 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();
    })();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    在安装完这些依赖后 我在启动下面的js时还是提示缺少库。如果不缺少可以跳过这里。(检查凡是就是执行上面的js是否报错)
    如:在调用chrome的时候缺少libdrm.so.2库

    error while loading shared libraries: libdrm.so.2: cannot open shared object file:
    
    • 1

    可以执行如下命令查看还缺那些库 ,cd后面是路径 一般报错里会有自己的路径。

     cd /xxx/xxx/puppeteer/chrome/linux-xxx/chrome-linux/
    ldd chrome
    
    • 1
    • 2

    执行完 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*
    
    • 1

    二、编写puppeteer服务js文件

    可以先新建一个目录如:puppeteer_project

    mkdir puppeteer_project
    
    • 1

    文件目录结构
    在这里插入图片描述
    **注意:**文件名最后不要随意改,因为相互之间有引用,要改文件名其他引用这个文件的地方也需要改。

    puppeteer_project
    	 --puppeteer-pool.js
    	--spider.js
    	--service.js
    
    • 1
    • 2
    • 3
    • 4

    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
    
    
    • 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

    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;
    
    
    • 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

    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('预渲染服务已启动!');
    });
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    引用js的下载,要不然可能找不到方法【 code: ‘MODULE_NOT_FOUND’,】

    npm install express --save
    npm install html-minifier --save
    
    • 1
    • 2

    执行启动puppeteer命令

    node server.js 
    或 
    node server.js &
    
    • 1
    • 2
    • 3

    后面带&的是后台运行,不带&的启动命令可以用来看日志,访问的链接会打印出来。
    相当与启动了一个端口为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;
      }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    修改完nginx conf文件之后可以执行

    nginx -t
    
    • 1

    检查配置是否格式正确,正确的话结果如下 最后有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
    
    • 1
    • 2

    之后再执行重启nginx即可。

     nginx -s reload
    
    • 1

    注意

    三、测试puppeteer配置

    可以使用postman调用接口测试
    headers里要加配置模仿爬虫参数。

    User-Agent:spider
    
    • 1

    测试puppeteer配置
    刚刚启动puppeteer(service.js)的时候访问可能比较慢,大几秒左右,启动半分钟左右再调用就会快一些,大概3秒能返回数据。具体访问速度可能和不同服务器有关。

    测试日志如下:
    在这里插入图片描述

    参考资料:
    Vue项目无需修改任何代码,就可实现SEO优化!

    如发现文章问题,欢迎评论或私信指出问题。

    如果这篇文章对您有帮助的话,可以点赞鼓励一下,谢谢!

  • 相关阅读:
    SAP Fiori应用索引大全工具和 SAP Fiori Tools 的使用介绍
    C++打怪升级(一)- 命名空间、缺省形参、重载
    掌握pandas cut函数,一键实现数据分类
    C专家编程 第3章 分析C语言的声明 3.3 优先级规则
    5、QT中SQLite数据库的操作
    使用ensp搭建路由拓扑,并使用ospf协议实现网络互通实操
    基于php+MySQL电脑外设商城网站 毕业设计-附源码271538
    vue子组件向父组件传值
    CCS3.3烧写说明
    垃圾分类小程序系统毕业设计,垃圾分类小程序系统设计与实现,垃圾分类系统毕设参考
  • 原文地址:https://blog.csdn.net/wuyuanshun/article/details/127737603