新闻爬虫与网页制作大作业

网页源代码预览

使用chrome浏览器打开新浪体育网的网址,按F12获取网页源代码,可以得到需要爬取的内容所在的位置(同理打开新浪军情网和雪球网)
在这里插入图片描述

MySQL数据库建表

在爬取网页数据之前,由于我们需要制作网页来展示爬虫结果,需要将爬虫得到的数据存入Mysql数据库中,以便于制作网页时可以在代码里用mysql模块来获取数据。
因此,在MySQL数据库中先建一个database,再在database里建一张sina表,用于存放所有爬取得到的新闻数据,包括有链接、标题、时间、来源、作者、文章id。

CREATE TABLE `sina` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',
  `href` varchar(250) NOT NULL COMMENT '链接',
  `title` varchar(50) NOT NULL COMMENT '标题',
  `time` varchar(50) NOT NULL COMMENT '时间',
  `source` varchar(50) NOT NULL COMMENT '来源',
  `author` varchar(50) NOT NULL COMMENT '作者',
  `articid` varchar(50) NOT NULL COMMENT '文章id',
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=13 DEFAULT CHARSET=utf8mb4 COMMENT='新浪军情表';

使用NodeJS来爬取网页数据

以爬取新浪军情网为例,
用loadPage函数,根据url,使用http模块,得到对应的html内容

function loadPage(url) {
    var http = require('http');
    var pm = new Promise(function (resolve, reject) {
        http.get(url, function (res) {
            var html = '';
            res.on('data', function (d) {
                html += d.toString()
            });
            res.on('end', function () {
                resolve(html);
            });
        }).on('error', function (e) {
            reject(e)
        });
    });
    return pm;
}

用InsertData函数,使用mysql模块,将爬取得到的数据存入MySQL表中

function insertData(arrData){
    var mysql = require('mysql');
    var connection = mysql.createConnection({
        host     : 'localhost',
        user     : 'root',
        password : '981003',
        database : 'tpshop'
    });

    var values = [
        ["index","www.alibaba.com",1],
        ["index1","www.google.com",1]
    ];
    var sql = "INSERT INTO sina(`href`,`title`,`time`,`source`,`author`,`articid`) VALUES ?";
    connection.query(sql, [arrData], function (err, rows, fields) {
    if(err){
                console.log('INSERT ERROR - ', err.message);
                connection.destroy();
                return;
            }
            console.log("INSERT SUCCESS");
            connection.destroy();
     });
}

使用cheerio模块,来解析html文档中的元素,定位到数据所在的位置,使用each方法来迭代获取每篇新闻的信息。最后调用InsertData函数,将爬取得到的数据存入MySQL的sina数据表中。

const cheerio = require('cheerio');
loadPage('http://mil.news.sina.com.cn/roll/index.d.html?cid=57918').then(function (d) {
    const $ = cheerio.load(d,{ 
         decodeEntities: false
    });
    const data=$('div[class=fixList]').html();
    console.log(data);
    const $2 = cheerio.load(data,{ 
         decodeEntities: false
    });
   var arrTime = [];
   $2('span').each(function(){
          var atime=$2(this).text();
          arrTime.push(atime);
    })

    var arrData=[];
    var index=0;
    $2('li a').each(function(){
         var ahref=$2(this).attr("href");
         var atitle=$2(this).text();
         var a=ahref.split('/');
         var aid=a[a.length-1];
         var num= aid.replace(/[^0-9]/ig,"");
         var insertItem="['"+ahref+"','"+atitle+"','"+arrTime[index++]+"','新浪网中国军情','','"+num+"']";
         arrData.push(insertItem);
      })       
    console.log(arrData);
    arrData="["+arrData+"]";
    var str=eval(arrData);
    insertData(str);
});

以类似的方法,也可以爬取得到另外两个网站(新浪体育网和雪球网)的信息。

使用HTML+CSS+NodeJS,来制作简单的新闻爬虫信息查询网页

在网页的前端,用户输入新闻的标题关键词和来源,前端将信息传送给后端进行处理

<!DOCTYPE html>
<html>
    <head>
        <title>新闻爬虫简单网页展示</title>
        <style type="text/css">
               h1{font-weight: bold; font-size:xx-large; color:red}
               br{font-style: italic;font-size: medium; color:yellow}
        </style>
    </head>
    <body>
        <h1>新闻爬虫简单网页展示</h1>
        <form action="http://127.0.0.1:8081/process_get" method="GET">
            <br> 标题:<input type="text" name="title">
            <br> 来源:<input type="text" name="source">
            <input type="submit" value="Submit">
        
        </form>

    </body>


</html>

后端通过接收前端出来的新闻标题关键字和来源,利用sql查询语言,在数据库中查询相关信息,并将查询结果以字符串的形式,传回前端页面进行显示

var express = require('express');
var mysql = require('./mysql.js');
var xlsx = require('node-xlsx');
var app = express();

app.use('/public',express.static('public'))
app.get('/index.html', function(req, res) {
    res.sendFile(__dirname + '/' + 'index.html');
})
app.get('/process_get', function(req, res) {
    res.writeHead(200, { 'Content-Type': 'text/html;charset=UTF8' }); 
    var fetchSql = "select href, author, time, source, articid from sina"
                   +" where title like '%" + req.query.title + "%'"
                   +" and source = '" + req.query.source + "'";
    
    var data = [];
    mysql.query(fetchSql, function(err, result, fields) {
        console.log(result);
      /*
        if(result)
        {
            for(var i = 0; i < result.length; i++)
			{
				var arr=[];
				var value=result[i];
				for(var j in value){
					arr.push(value[j]);
				}
                //data.push(arr);
                var str = arr.join('\t');
                data.push(str+'\r');
			}
        }
        
        var str2 = data.join('\r')
        res.end(str2);
        */
       // res.end(table)
        res.end(JSON.stringify(result));
    });
})
var server = app.listen(8081, function() {
    console.log("正在访问 http://127.0.0.1:8081/index.html")
})

命令行运行后端js程序,并用浏览器打开前端html,输入信息查询后,发现结果都是json格式的字符串,且无法换行,显得比较混乱
在这里插入图片描述

使用express模块的脚手架,来优化网页前端展示

先npm安装express-generator,之后在命令行用express -e search命令,自动创建一个search文件夹,该文件夹中的public/search.html为新网页的前端,routes/index.js为新网页的后端。

search.html的代码如下所示:

<!DOCTYPE html>
<html>
<header>
    <style type="text/css">
        h1{font-weight: bold; font-size:xx-large; color:red}
        p{font-style: italic;font-size:x-large; color:orange}
        input[type='text']{
            box-sizing: border-box;
            text-align:center;
            font-size:1.4em;
            height:2.7em;
            border-radius:4px;
            border:1px solid #c8cccf;
            color:#6a6f77;
            -web-kit-appearance:none;
            -moz-appearance: none;
            display:block;
            outline:0;
            padding:0 1em;
            text-decoration:none;
            width:50%;
            }
        input[type='button']{
            color:red;
            background: #acacac;
            font-size: x-large;
            }

        
   </style>
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
</header>

<body>
    <form>
        <h1>新闻爬虫简单网页</h1>
        <br> <p>标题:</p><input type="text" name="title" id="title">
        <br> <p>来源:</p><input type="text" name="source" id="source">
        <input class="form-submit" type="button" value="查询">
    </form>
    <div class="cardLayout" style="margin: 10px 0px">
        <table width="100%" id="record2"></table>
    </div>
    <script>
        $(document).ready(function() { //网页加载完之后执行的函数
            $("input:button").click(function() { //按钮点击时执行的函数
                $.get('/process_get?title=' + $("input[name='title']").val() +'&source='+ $("input[name='source']").val(),function(data) { 
                    $("#record2").empty(); //清空原列表
                    $("#record2").append('<tr class="cardLayout"><td>url</td><td>source_name</td>' +
                        '<td>title</td><td>author</td><td>publish_date</td></tr>'); //添加表头
                    for (let list of data) { //遍历添加数据
                        let table = '<tr class="cardLayout"><td>';
                        Object.values(list).forEach(element => {
                            table += (element + '</td><td>');
                        });
                        $("#record2").append(table + '</td></tr>');
                    }
                });
            });

        });
    </script>
</body>

</html>

index.js的代码如下所示:

var express = require('express');
var router = express.Router();
var mysql = require('../mysql.js');
/* GET home page. */
router.get('/', function(req, res, next) {
  res.render('index', { title: 'Express' });
});

module.exports = router;
router.get('/process_get', function(request, response) {
  console.log(request.query.title);
  var fetchSql = "select href, source, title, author, time from sina"
                   +" where title like '%" + request.query.title + "%'"
                   +" and source = '" + request.query.source + "'";
  mysql.query(fetchSql, function(err, result, fields) {
      response.writeHead(200, {
        "Content-Type": "application/json"
      });
      //console.log(result)
      response.end(JSON.stringify(result));
      response.end();

  });
})

具体的网页功能不变,还是用户在html页面上先输入新闻标题关键字和来源,点击查询按钮,在该页面上就会自动返回格式化的数据库查询结果,看起来更加清晰明了~
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值