nodejs爬虫项目(二)

之前已经爬取了多个网站的新闻数据,现在要对这些数据进行整理展示,具体要求如下
nodejs爬虫项目(二)_第1张图片
首先第一步要在final-project文件夹下npm install安装依赖包
这里我在安装过程中遇见了问题,安装一直失败而且安装进度非常慢,百度了一下大体了解到这是从国外的镜像服务器下获取包的资源,所以猜测可能和我家的网络有关。果然,在连接了学校的VPN之后再运行npm install很快就安装完成了(有一说一,移动的网真滴不行)。
nodejs爬虫项目(二)_第2张图片
接下来需要访问之前已经安装好的mysql数据库,新建立两个mysql表用来保存用户的操作日志,具体过程和代码如下
nodejs爬虫项目(二)_第3张图片

具体代码
--创建用户信息数据表 CREATE TABLEcrawl.user(idINT UNSIGNED NOT NULL AUTO_INCREMENT,usernameVARCHAR(45) NOT NULL,passwordVARCHAR(45) NOT NULL,registertimedatetime DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id), UNIQUE KEYusername_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配置文件nodejs爬虫项目(二)_第4张图片
接下来需要完全用户可注册登录网站,非注册用户不可登录查看数据,对于登录和注册时的错误也要有适当的提示,例如登陆时
提示用户名或密码输错,用户不存在,注册时,两次密码不一致,用户已存在或者注册成功跳转登陆页.。
首先是登录页面的代码nodejs爬虫项目(二)_第5张图片
先引入先引入angular.js,这样登陆成功会跳转到news.html页面,然后是注册页的代码nodejs爬虫项目(二)_第6张图片
用户可注册登录网站,非注册用户不可登录查看数据这一部分用JavaScript来实现,由于代码比较少,就直接写在登录页的html里了nodejs爬虫项目(二)_第7张图片
在登录页路由中,首先调用userDAO,然后保存session信息,不然记录用户操作日志时,不知道是哪位用户进行的操作。nodejs爬虫项目(二)_第8张图片
UserDAO的代码实现以及之前提到的session的设置如下nodejs爬虫项目(二)_第9张图片
nodejs爬虫项目(二)_第10张图片
注册操作和退出登录的实现,注意退出时清除sessionnodejs爬虫项目(二)_第11张图片
nodejs爬虫项目(二)_第12张图片
然后实现查询功能,先写好查询页面的代码,然后在news.html里将其引入

            
        
序号 标题 作者 关键词 链接 发布时间
{{index+key}} {{item.title}} {{item.author}} {{item.keywords}} {{item.url}} {{item.publish_date}}
    
    

nodejs爬虫项目(二)_第13张图片
nodejs爬虫项目(二)_第14张图片
第52行,拼路由,get方法传给后端处理。其中排序是按照发表时间排的,也是传的参数,也在路由中,查询页路由的代码如下
nodejs爬虫项目(二)_第15张图片
用newsDAO.search函数实现查询词支持布尔表达式,主要是拼起sql。

var mysql = require(‘mysql’); var mysqlConf = require(’…/conf/mysqlConf’); var pool =
mysql.createPool(mysqlConf.mysql);

module.exports = {
query_noparam :function(sql, callback) {
pool.getConnection(function(err, conn) {
if (err) {
callback(err, null, null);
} else {
conn.query(sql, function(qerr, vals, fields) {
conn.release(); //释放连接
callback(qerr, vals, fields); //事件驱动回调
});
}
});
},
search :function(searchparam, callback) {
// 组合查询条件
var sql = 'select * from fetches ';

    if(searchparam["t2"]!="undefined"){
        sql +=(`where title like '%${searchparam["t1"]}%' ${searchparam['ts']} title like '%${searchparam["t2"]}%' `);
    }else if(searchparam["t1"]!="undefined"){
        sql +=(`where title like '%${searchparam["t1"]}%' `);
    };

    if(searchparam["t1"]=="undefined"&&searchparam["t2"]=="undefined"&&searchparam["c1"]!="undefined"){
        sql+='where ';
    }else if(searchparam["t1"]!="undefined"&&searchparam["c1"]!="undefined"){
        sql+='and ';
    }

    if(searchparam["c2"]!="undefined"){
        sql +=(`content like '%${searchparam["c1"]}%' ${searchparam['cs']} content like '%${searchparam["c2"]}%' `);
    }else if(searchparam["c1"]!="undefined"){
        sql +=(`content like '%${searchparam["c1"]}%' `);
    }

    if(searchparam['stime']!="undefined"){
        if(searchparam['stime']=="1"){
            sql+='ORDER BY publish_date ASC ';
        }else {
            sql+='ORDER BY publish_date DESC ';
        }
    }

    sql+=';';
    pool.getConnection(function(err, conn) {
        if (err) {
            callback(err, null, null);
        } else {
            conn.query(sql, function(qerr, vals, fields) {
                conn.release(); //释放连接
                callback(qerr, vals, fields); //事件驱动回调
            });
        }
    });
},;

查询结果的展示nodejs爬虫项目(二)_第16张图片

第47行,ng-show 是在点击显示图表的时候,先隐藏掉这些查询结果再显示图片;也控制先点击图表,再点击查询的时候,将图表显示隐藏掉,再展示查询结果。
当页面列表的爬虫数据过多时,需要对列表内容进行分页,这边使用了angularjs分页的实现,不需要后台配合,前台一次性拿完所有的数据然后进行分页展示。缺点数据量过大的时候页面加载效率比较低,但界面上对用户更加友好。下面是实现分页的代码。nodejs爬虫项目(二)_第17张图片
nodejs爬虫项目(二)_第18张图片
初始化的时候,首先要显示第一页的内容,同时算好一共分多少页(75行),pageList是一个最多长为5的数组,表示右下角截图的框里最多展示5个页码。nodejs爬虫项目(二)_第19张图片
当选中其它页面的时候,由于最多显示五个页面,右下角的页面数字也要随之改变,具体代码实现如下。
nodejs爬虫项目(二)_第20张图片
nodejs爬虫项目(二)_第21张图片
下一步是添加数据分析图表,以柱状图的代码为例
前端代码

$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 {

                    // var newdata = washdata(data);
                    let xdata = [], ydata = [], newdata;

                    var pattern = /\d{4}-(\d{2}-\d{2})/;
                    res.data.result.forEach(function (element) {
                        // "x":"2020-04-28T16:00:00.000Z" ,对x进行处理,只取 月日
                        xdata.push(pattern.exec(element["x"])[1]);
                        ydata.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;
            });

};

路由代码

router.get(’/histogram’, function(request, response) {
//sql字符串和参数
console.log(request.session[‘username’]);

//sql字符串和参数
if (request.session['username']===undefined) {
    // response.redirect('/index.html')
    response.json({message:'url',result:'/index.html'});
}else {
    var fetchSql = "select publish_date as x,count(publish_date) as y from fetches group by publish_date order by publish_date;";
    newsDAO.query_noparam(fetchSql, function (err, result, fields) {
        response.writeHead(200, {
            "Content-Type": "application/json",
            "Cache-Control": "no-cache, no-store, must-revalidate",
            "Pragma": "no-cache",
            "Expires": 0
        });
        response.write(JSON.stringify({message:'data',result:result}));
        response.end();
    });
}

});
最后将用户注册、登录、查询等操作记入数据库中的日志,直接在app.js中,引入var logger = require('morgan’);
借助中间件保存的信息nodejs爬虫项目(二)_第22张图片
保存的操作日志可以在mysql数据库中查询,输入select * from user_factionnodejs爬虫项目(二)_第23张图片
附上完整的演示
在final_project文件夹下cmd运行node bin/wwwnodejs爬虫项目(二)_第24张图片
进入http://localhost:3000/,并进行注册nodejs爬虫项目(二)_第25张图片
搜索疫情,结果如下nodejs爬虫项目(二)_第26张图片
nodejs爬虫项目(二)_第27张图片
数据分析图表nodejs爬虫项目(二)_第28张图片
nodejs爬虫项目(二)_第29张图片
nodejs爬虫项目(二)_第30张图片

你可能感兴趣的:(爬虫)