首页 > 其他分享 >使用PhantomJS解决VUE项目无法被百度收录

使用PhantomJS解决VUE项目无法被百度收录

时间:2023-04-21 17:35:39浏览次数:30  
标签:function VUE PhantomJS server 收录 var js page 加载

一、安装PhantomJS

安装文章:https://www.cnblogs.com/robots2/p/17340143.html

二、编写脚本spider.js

// spider.js
'use strict';

console.log('=====start=====');

// 单个资源等待时间,避免资源加载后还需要加载其他资源
var resourceWait = 500;
var resourceWaitTimer;

// 最大等待时间
var maxWait = 5000;
var maxWaitTimer;

// 资源计数
var resourceCount = 0;

// PhantomJS WebPage模块
var page = require('webpage').create();

// NodeJS 系统模块
var system = require('system');

// 从CLI中获取第二个参数为目标URL
var url = system.args[1];

// 设置PhantomJS视窗大小
page.viewportSize = {
	width: 1280,
	height: 1014,
};

// 获取镜像
var capture = function (errCode) {
	// 外部通过stdout获取页面内容
	console.log(page.content);

	// 清除计时器
	clearTimeout(maxWaitTimer);

	// 任务完成,正常退出
	phantom.exit(errCode);
};

// 资源请求并计数
page.onResourceRequested = function (req) {
	resourceCount++;
	clearTimeout(resourceWaitTimer);
};

// 资源加载完毕
page.onResourceReceived = function (res) {
	// chunk模式的HTTP回包,会多次触发resourceReceived事件,需要判断资源是否已经end
	if (res.stage !== 'end') {
		return;
	}

	resourceCount--;

	if (resourceCount === 0) {
		// 当页面中全部资源都加载完毕后,截取当前渲染出来的html
		// 由于onResourceReceived在资源加载完毕就立即被调用了,我们需要给一些时间让JS跑解析任务
		// 这里默认预留500毫秒
		resourceWaitTimer = setTimeout(capture, resourceWait);
	}
};

// 资源加载超时
page.onResourceTimeout = function (req) {
	resouceCount--;
};

// 资源加载失败
page.onResourceError = function (err) {
	resourceCount--;
};

// 打开页面
page.open(url, function (status) {
	if (status !== 'success') {
		phantom.exit(1);
	} else {
		// 当改页面的初始html返回成功后,开启定时器
		// 当到达最大时间(默认5秒)的时候,截取那一时刻渲染出来的html
		maxWaitTimer = setTimeout(function () {
			capture(2);
		}, maxWait);
	}
});

测试脚本

phantomjs spider.js 'www.baidu.com'

三、做成node服务,编写server.js

// server.js
// ExpressJS调用方式
var express = require('express');
var app = express();

// 引入NodeJS的子进程模块
var child_process = require('child_process');

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

    // 完整URL
    var url = req.protocol + '://'+ req.hostname + req.originalUrl;

    // 预渲染后的页面字符串容器
    var content = '';

    // 开启一个phantomjs子进程
    var phantom = child_process.spawn('phantomjs', ['spider.js', url]);

    // 设置stdout字符编码
    phantom.stdout.setEncoding('utf8');

    // 监听phantomjs的stdout,并拼接起来
    phantom.stdout.on('data', function(data){
        content += data.toString();
    });

    // 监听子进程退出事件
    phantom.on('exit', function(code){
        switch (code){
            case 1:
                console.log('加载失败');
                res.send('加载失败');
                break;
            case 2:
                console.log('加载超时: '+ url);
                res.send(content);
                break;
            default:
                res.send(content);
                break;
        }
    });

});

app.listen(3000, function () {
  console.log('Spider app listening on port 3000!');
});

测试脚本node server.js

运行稳定后可后台运行node服务:nohup node server.js &

四、修改nginx配置,使得常建的爬虫跳转到该node服务上

upstream spider_server {
  server localhost:3000;
}

server {
    listen       80;
    server_name  example.com;
    
    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;

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

 

测试收录的url

curl 'https://www.baidu.com/#/page/2210574586898432' -H 'User-Agent: Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)'

 

 

参考文章:https://juejin.cn/post/7033661909756968973

 

 

标签:function,VUE,PhantomJS,server,收录,var,js,page,加载
From: https://www.cnblogs.com/robots2/p/17341166.html

相关文章

  • vue下拉框选择后不显示值,选其他下拉框后才显示出来
    vue下拉框选择后不显示值,选其他下拉框后才显示出来 vue也太坑了解决方法:为该el-select添加change事件中使用$set来对属性赋值,如下:changeData(val){ this.$set(this.formData,this.formData.id,val.value)}......
  • vue全家桶进阶之路50:Vue3 环境变量+跨域设置实例
    使用.env加后缀的方式来建立某个模式下的环境变量,例如:项目根目录新建两个环境变量文件(development开发环境和production生产环境):.env.development.env.production 在新建的两个环境变量文件中设置相同的环境变量名:VUE_APP_BASE_API环境变量名称必须以"VUE_API_"+名称......
  • vue-input-directive 插件的使用(已兼容vue3.0)
    codepen体验地址github地址安装、引入npminstallvue-input-directive--saveimportVuefrom'vue'importinputValidatefrom'vue-input-directive'Vue.use(inputValidate)1、d-input-max 输入数字限制最大值<el-inputv-d-input-max="99.99"v-......
  • Vue3 代码块高亮显示并可使用富文本编辑器编辑(highlight.js + wangEditor)
    在Vue项目中实现以下功能:  功能1.在页面中显示代码,并将其中的关键字高亮显示。  功能2.允许对代码块进行编辑,编辑时代码关键字也高亮显示。  功能3.可在编辑器中添加多个代码块,动态渲染代码关键字高亮。 Step1:安装所需插件(本文使用npm安装,若需使用其他方式请查......
  • vue兼容IE的方法规范
    第三方插件的兼容性需经过ie和国产电脑浏览器测试后,才可以使用。1、main.js顶部添加babel-polyfillimport'babel-polyfill'importVuefrom'vue'importAppfrom'./App.vue'importrouterfrom'./router'importstorefrom'./store'2、js-base6......
  • VUE学习笔记
    VUE学习笔记1.函数体格式简写格式:“方法名(){}”===>全写格式:“方法名:function(){}”2.定义对象格式对象名:{}3.全局事件总线相关的函数注册全局事件总线:在main.js的VUE实例中创建事件总线beforeCreate(){ Vue.prototype.$bus=this },1.$emit1、this.$emit('自......
  • vue3 文件上传,fileChange中的一个问题,第二个参数问题
    这里fileChange第二个参数,不可也用fileList会污染已经定义的响应式变量fileList<scriptsetup>constfileList=ref([])constfileChange=(file,fileList)=>{fileList.value=fileList;}</script>这里第二个参数不好再用fileList,因为上面已经定义了响应式对象......
  • vue2源码-十一、Vue的生命周期
    Vue的生命周期钩子函数是如何实现?内部利用一个发布订阅模式,将用户写的钩子维护成一个数组,后续依次调用hooks。主要靠的是mergerOptions方法有哪些?引用自https://vue3js.cn/interview/vue/lifecycle.html#%E4%BA%8C%E3%80%81%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F%E6%9C%......
  • vue实现的常见的动画效果
    本文包括的动画:zoom-inzoom-in-leftzoom-in-rightzoom-in-topzoom-in-bottomzoom-in-center-xzoom-in-center-yslideslide-leftslide-rightslide-topslide-bottomzoom-in-left.ivy-zoom-in-left-enter-active,.ivy-zoom-in-left-leave-active{transi......
  • vue3打包后一片空白控制台报错
    问题原因是路径不对,加上一行代码就可完美解决问题。在vue.config文件中加上  publicPath:'./' 即可解决问题。问题如图所示: 如何解决问题呢?     ......