作业要求
一、登录注册页面
检测用户名密码是否一致,是则跳转至新闻页面
增加注册用户
登录界面如下:
发现自己实在是不太了解bootstrap的各种样式,界面也不知道该怎么优化,后面的html文档的css就都用的老师给的模板了 -_-||
二、操作记录保留
首先先在数库中建立两张表,一个存放已注册的用户账号密码。另一个存放用户操作记录:
CREATE TABLE `crawl`.`user` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`username` VARCHAR(45) NOT NULL,
`password` VARCHAR(45) NOT NULL,
`registertime` datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `username_UNIQUE` (`username`))
ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `crawl`.`user_action` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`username` VARCHAR(45) NOT NULL,
`request_time` VARCHAR(45) NOT NULL,
`request_method` VARCHAR(20) NOT NULL,
`request_url` VARCHAR(300) NOT NULL,
`status` int(4),
`remote_addr` VARCHAR(100) NOT NULL,
PRIMARY KEY (`id`))
ENGINE=InnoDB DEFAULT CHARSET=utf8;
然后设置mysql配置文件:
module.exports = {
mysql: {
host: 'localhost',
user: '***',
password: '***',
database:'***',
connectionLimit: ***
}};
账号密码表:
操作记录表:
三、查询数据与分页
数据查询代码:
$scope.search = function () {
var title1 = $scope.title1;
var title2 = $scope.title2;
var selectTitle = $scope.selectTitle;
var content1 = $scope.content1;
var content2 = $scope.content2;
var selectContent = $scope.selectContent;
var sorttime = $scope.sorttime;
if(typeof title1=="undefined" && typeof title2!="undefined" && title2.length>0){
title1 = title2;
}
if(typeof content1=="undefined" && typeof content2!="undefined" && content2.length>0){
content1 = content2;
}
var myurl = `/news/search?t1=${title1}&ts=${selectTitle}&t2=${title2}&c1=${content1}&cs=${selectContent}&c2=${content2}&stime=${sorttime}`;
http.get(myurl).then( function (res) {
if(res.data.message=='data'){
$scope.isisshowresult = true;
$scope.initPageSort(res.data.result)}
else {
window.location.href=res.data.result;
}},function (err) {$scope.msg = err.data;});
};
分页功能的实现:
$scope.initPageSort=function(item){
$scope.pageSize=5;
$scope.selPage = 1;
$scope.data = item;
$scope.pages = Math.ceil($scope.data.length / $scope.pageSize);
$scope.pageList = [];
$scope.index = 1;
var len = $scope.pages> 5 ? 5:$scope.pages;
$scope.pageList = Array.from({length: len}, (x,i) => i+1);
$scope.items = $scope.data.slice(0, $scope.pageSize);
};
$scope.selectPage = function (page) {
if (page < 1 || page > $scope.pages) return;
var pageList = [];
if(page>2){
for (var i = page-2; i <= $scope.pages && i < page+3; i++) {
pageList.push(i);
}
}
else {
for (var i = page; i <= $scope.pages && i < page+5; i++) {
pageList.push(i);
}
}
$scope.index =(page-1)*$scope.pageSize+1;
$scope.pageList = pageList;
$scope.selPage = page;
$scope.items = $scope.data.slice(($scope.pageSize * (page - 1)), (page *
$scope.pageSize));
console.log("选择的页:" + page);
};
添加查看查询结果返回首页、尾页、任意页功能:
<script>
//返回到首页
$scope.First = function () {
$scope.selectPage(1);
};
//跳转至尾页
$scope.Previous = function () {
$scope.selectPage($scope.selPage - 1);
};
//跳转至所输入的页
$scope.toThePage=undefined;
$scope.ToThePage = function () {
$scope.selectPage($scope.toThePage);
$scope.toThePage = undefined;
}
</script>
<a ng-click="First()" role="button"><span role="button">首页</span></a>
<a ng-click="Previous()" role="button"><span role="button">上一页</span></a>
<input type="text" placeholder="页码" style="height:33px; width:40px;" ng-model="$parent.toThePage">
<a ng-click="ToThePage()" role="button"><span role="button" >跳转到</span></a>~
四、数据可视化
选用Echarts对爬取到的数据进行一个直观的解明:
(1)柱状图
$scope.histogram = function () {
$scope.isShow = false;
$http.get("/news/histogram").then(
function (res) {
if(res.data.message=='url'){
window.location.href=res.data.result;
}
else {
let xdata = [], ydata = [], newdata;
var pattern = /\d{4}-(\d{2}-\d{2})/;
res.data.result.forEach(function (element) {
xdata.push(pattern.exec(element["x"])[1]);
data.push(element["y"]);
});
newdata = {"xdata": xdata, "ydata": ydata};
var myChart = echarts.init(document.getElementById('main1'));
var option = {
title: {
text: '新闻发布数 随时间变化' },
tooltip: {},
legend: {
data: ['新闻发布数'] },
xAxis: {
data: newdata["xdata"]},
yAxis: {},
series: [{
name: '新闻数目',
type: 'bar',
data: newdata["ydata"]
}]
};
myChart.setOption(option);
}
}, function (err) {
$scope.msg = err.data;
});
};
例子:
(2)饼图:
$scope.pie = function () {
$scope.isShow = false;
$http.get("/news/pie").then(function (res) {
if(res.data.message=='url'){
window.location.href=res.data.result;
}
else {
let newdata = [];
var pattern = /编辑:[\u4E00-\u9FA5]+/;
res.data.result.forEach(function (element) {
newdata.push({name: pattern.exec(element["x"]) , value:
element["y"]});
});
var myChart = echarts.init(document.getElementById('main1'));
var app = {};
option = null;
var option = {
title: {
text: '作者发布新闻数量',
x: 'center'
},
tooltip: {
trigger: 'item',
formatter: "{a} <br/>{b} : {c} ({d}%)"
},
legend: {
orient: 'vertical',
left: 'left',
},
series: [
{
name: '访问来源',
type: 'pie',
radius: '55%',
center: ['50%', '60%'],
data: newdata,
itemStyle: {
emphasis: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)
}
}
}
]
};
app.currentIndex = -1;
setInterval(function () {
var dataLen = option.series[0].data.length;
myChart.dispatchAction({
type: 'downplay',
seriesIndex: 0,
dataIndex: app.currentIndex
});
app.currentIndex = (app.currentIndex + 1) % dataLen;
myChart.dispatchAction({
type: 'highlight',
seriesIndex: 0,
dataIndex: app.currentIndex
});
myChart.dispatchAction({type: 'showTip',seriesIndex: 0, dataIndex: app.currentIndex});}, 1000);
if (option && typeof option === "object") {
yChart.setOption(option, true);
} ;
}
});
};
例子:
各个网站对于编辑的格式不一甚至可能一篇文章没有作者,所以汇总在一起以后很难用正则表达式把作者名取出来,故饼图的很多部分作者名为空。
(3)折线图
本来是想在网页输入关键词进行实时更新折线图的,但是我发现折线图仿佛有惰性,刷新页面并不会更新折线图,只能在终端退出以后重新node www文件并重新登录才能更新,所以就放弃了。
$scope.line = function () {
$scope.isShow = false;
$http.get("/news/line").then(
function (res) {
if(res.data.message=='url'){
window.location.href=res.data.result;
}
else {
var myChart = echarts.init(document.getElementById("main1"));
option = {
title: {
text: '"***"该词在新闻中的出现次数随时间变化图' },
xAxis: {
type: 'category',
data: Object.keys(res.data.result
)
},
yAxis: {
type: 'value'
},
series: [{
data: Object.values(res.data.result),
type: 'line',
itemStyle: {normal: {label: {show: true}}}
}],
};
if (option && typeof option === "object") {
myChart.setOption(option, true);
}
}
});
};
例子:
(4)词云
$scope.wordcloud = function () {
$scope.isShow = false;
$http.get("/news/wordcloud").then(
function (res) {
if(res.data.message=='url'){
window.location.href=res.data.result;
}else {
var mainContainer = document.getElementById('main1');
var chart = echarts.init(mainContainer);
var data = [];
for (var name in res.data.result) {
data.push({
name: name,value: Math.sqrt(res.data.result[name]) }) }
var maskImage = new Image();
maskImage.src = './images/logo.png';
var option = {
title: {
text: '所有新闻内容 jieba分词 的词云展示'
},
series: [{
type: 'wordCloud',
sizeRange: [12, 60],
rotationRange: [-90, 90],
rotationStep: 45,
gridSize: 2,
shape: 'circle',
maskImage: maskImage,
drawOutOfBound: false,
textStyle: {
normal: {
fontFamily: 'sans-serif',
fontWeight: 'bold',
color: function () {
return 'rgb(' + [
Math.round(Math.random() * 160),
Math.round(Math.random() * 160),
Math.round(Math.random() * 160)
].join(',') + ')';
}
},
emphasis: {
shadowBlur: 10,
shadowColor: '#333'
}
},
data: data
}]
};
maskImage.onload = function () {
chart.clear();
chart.setOption(option); };
window.onresize = function () {
chart.resize();
};
}
});
}~
例子:
总结
相比期中的作业,本次大作业对我来说是蛮有难度的,代码多数也是用了老师的代码,我更多的是依葫芦画瓢在模仿写跳转页等而非有什么新东西,路由方面的设置也不太会写。听说油管等外网有很多优秀的前端开发教程,希望在后续的学习中能学会一些,不再面对各科大作业时心中发怵。