新闻爬虫与网页制作大作业
网页源代码预览
使用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页面上先输入新闻标题关键字和来源,点击查询按钮,在该页面上就会自动返回格式化的数据库查询结果,看起来更加清晰明了~