这次的项目前瞻工作是实现一个网页爬取数据,然后将数据显示到微信公众号当中。最初计划是使用Java爬虫技术,爬取网页,用html解析技术进行解析,然后将数据进行业务处理后返回给前端。但是这样一套之前还未接触,而且服务端做的工作比较大,就考虑到是否可以在前端实现这样的需求。
虽然没有接触过爬虫,但是如果只是发送网页请求,拿去数据,在进行处理,貌似前端还真的可以实现。当时想的是,vue-cli处理跨域问题,axios直接请求官网首页,返回html的数据,然后是用JQuery的DOM遍历获取指定数据即可。
下面进入正题。
前端技术的话,只要选择Vue-CLI+JQuery+axios。
选择Vue-CLI一方面是脚手架方便快速搭建前端的单页面应用,另一方面,也是最主要的方面,利用其代理功能,解决请求的跨域问题(因为一般访问别的项目或者接口,因为IP和端口不一致会遇到课跨域问题,数据不能再浏览器正常显示)。
选择JQuery的主要原因:
选择axios顾名思义,为了发送异步请求。
Vue-CLI项目和安装axios比较简单,就不多说。主要讲述下Vue-CLI如何安装JQuery。
npm install jquery --save
在项目根目录下的package.json 文件内的 “eslintConfig"中检查,看’env对象下面是否有"jquery”:true (如没有 则需手动添加)
在文件根目录下新建vue.config.js文件 , 在文件中添加如下代码:
const webpack = require('webpack')
module.exports = {
configureWebpack: {
plugins: [
new webpack.ProvidePlugin({
$:"jquery",
jQuery:"jquery",
"windows.jQuery":"jquery"
})
]
},
}
import $ from 'jquery'
(经测试不引入,也可以使用)附:
在根目录下新建vue.config.js文件 ,然后在里面添加配置信息和老版本cli在webpack.config.js 中添加配置是一样的效果,这是因为vue-cli3内部高度集成了webpack,一般来说使用者不需要再去知道weboack做了什么,所以没有暴露webpack的配置文件,但我们依然可以创建vue.config.js 去修改默认webpack配置。
在vue.config.js
下进行配置
在devServer下的proxy进行配置,可以参考官网的配置:
https://cli.vuejs.org/zh/config/#devserver-proxy
这里是只要在访问路径上加上/static
都会被应用到这个规则,并且将/static
去掉。假设访问路径是http://127.0.0.1:8070/static/info/index.html
那么代理之后的路径就会变为http://tzb.xxu.edu.cn/info/index.html
。
附:vue.config.js配置
const webpack = require('webpack');
module.exports = {
// publicPath: './', //vue3 解决部署到服务器白屏问题 '/' => ''
outputDir: 'dist',
devServer: {
// 项目运行时候的端口号
host: "127.0.0.1",
port: 8070,
proxy: {
'/static': {
target: 'http://tzb.xxu.edu.cn',//后台接口
ws: false, //如果要代理websockets
secure: false, // 使用的是http协议则设置为false,https协议则设置为true
changeOrigin: true, //将选项changeOrigin设置true为基于名称的虚拟托管站点。
pathRewrite: { //重写路径 比如'/api/aaa/ccc'重写为'/aaa/ccc'
'^/static': ''
}
}
}
},
//警告 webpack 的性能提示
//解决警告——Vue-cli3 WARNING in asset size limit: The following asset(s) exceed the recommended size limit (244 KiB)
configureWebpack: {
performance: {
hints: 'warning',
//入口起点的最大体积 整数类型(以字节为单位)
maxEntrypointSize: 50000000,
//生成文件的最大体积 整数类型(以字节为单位 300k)
maxAssetSize: 30000000,
//只给出 js 文件的性能提示
assetFilter: function (assetFilename) {
return assetFilename.endsWith('.js');
}
},
plugins: [
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery",
"windows.jQuery": "jquery"
})
]
}
};
以CSDN为例
新乡学院党委统战部网址:http://tzb.xxu.edu.cn
那么首先我们需要将vue.config.js的代理目标网址设置为http://tzb.xxu.edu.cn
附:如果有多个网站需要进行爬取,那么可以将/static
这样的规则设置成多套,一个规则,对应一个代理规则。
proxy: {
'/static': {
target: 'http://tzb.xxu.edu.cn',//后台接口
ws: false, //如果要代理websockets
secure: false, // 使用的是http协议则设置为false,https协议则设置为true
changeOrigin: true, //将选项changeOrigin设置true为基于名称的虚拟托管站点。
pathRewrite: { //重写路径 比如'/api/aaa/ccc'重写为'/aaa/ccc'
'^/static': ''
}
}
}
请求:
// /static后什么不加,会被代理到http://tzb.xxu.edu.cn
axios.get("/static")
.then(resp => {
console.log(resp );
//转为jquery对象
let htmlDom = $(resp.data);
});
可以拿到这个网页的全部数据,将resp.data转为jquery对象后,就可以使用DOM遍历获取相应的数据
新乡学院党委统战部的党派团体通知为例:
我们可以通过JQuery的DOM操作,拿到通知的标题,内容详情链接、发布时间等等相关信息。
请求代码
通过指定的class或者id,拿到父级节点或者子级节点的数据。
// /static后什么不加,会被代理到http://tzb.xxu.edu.cn/dptt.htm
axios.get("/static/dptt.htm")
.then(resp => {
let dataList = [];
//转为jquery对象
let htmlDom = $(resp.data);
//DOM遍历
let titleList = htmlDom.find(.c124818);
let dataTimeList = htmlDom.find(.timestyle124818);
for (let i = 0; i < titleList.length; i++) {
let title = $(titleList[i]);
let dateTime = $(dataTimeList[i]);
if (title.text() !== "" && title.text() !== undefined) {
let data = {
title: "",
path: "",
dataTime: ""
};
data.title = title.text();
data.path = title.eq(0).attr("href");
data.dataTime = dateTime.text();
dataList.push(data);
}
}
});
完整代码
<template>
<div>
<p>通知公告</p>
<ul id="notice" v-for="(data,index) in list" :key="index">
<li>
<a href="javascript:void(0);" @click="toContent(data.path)">{{data.title}}</a>
<p class="dataTime">{{data.dataTime}}</p>
</li>
</ul>
<p v-if="isBottom">---已经到底了---</p>
</div>
</template>
<script>
import api from "../api/list"
export default {
name: 'List',
data() {
return {
//列表数据
list: [],
}
},
mounted() { // 渲染后执行
// 查询数据
this.getData();
},
methods: {
getData: function () { // 从服务的加载数的方法。
// /static后什么不加,会被代理到http://tzb.xxu.edu.cn/dptt.htm
axios.get("/static/dptt.htm")
.then(resp => {
let dataList = [];
//转为jquery对象
let htmlDom = $(resp.data);
let titleList = htmlDom.find(.c124818);
let dataTimeList = htmlDom.find(.timestyle124818);
for (let i = 0; i < titleList.length; i++) {
let title = $(titleList[i]);
let dateTime = $(dataTimeList[i]);
if (title.text() !== "" && title.text() !== undefined) {
let data = {
title: "",
path: "",
dataTime: ""
};
data.title = title.text();
data.path = title.eq(0).attr("href");
data.dataTime = dateTime.text();
this.list.push(data);
}
}
});
}
}
}
</script>
<style scoped>
h3 {
margin: 40px 0 0;
}
ul {
list-style-type: none;
padding: 0;
text-align: left;
width: 30rem;
margin: 0 auto;
}
li {
display: inline-block;
margin: 1rem 0;
}
a {
color: #42b983;
text-decoration: none;
}
p {
margin: 0;
padding: 0;
}
.dataTime {
color: #aaa;
}
</style>