文章目录

  • 一、新闻爬取
    • 1.爬虫原理
    • 2.分析网站链接格式和网页信息格式
      • cheerio
      • 爬取新浪新闻
      • 爬取人民网新闻
      • 央视新闻爬取
      • 网易新闻
    • 3.数据库设计
    • 4.爬虫具体代码实现
    • 5.存储结果展示
  • 二、 网站搭建
    • 1.用express构建网站访问mysql
    • 2.显示查询结果
      • 后端实现
      • 前端实现
    • 3.对查询结果进行分页
    • 4.优化页面
    • 5.时间热度分析
      • 后端
      • 前端
    • 6.结果展示
  • 三、错误处理
    • 1.TypeError [ERR_INVALID_ARG_TYPE]: 报错
    • 2.爬虫得到的数据出现中文乱码
    • 3.MAC mysql密码输入正确的情况下报错
    • 4.npm audit fix 解决方法
  • 四、总结

一、新闻爬取

一共选了四个新闻网站进行爬虫,分别是人民网新浪新闻网易新闻央视新闻,其中主要爬取的网站是人民网和新浪新闻(爬取多天数据、总数据量达1360条)并且将爬取结果存储在mysql中。

上demo

新闻网站demo|时间热度分析

1.爬虫原理

  1. 首先我们搜索主页面,获取我们想要的子网页的URL
    通过request请求,cheerio解析,each遍历
  2. 搜索出我们子网页页面中我们需要的信息:标题,正文等
    通过request请求,cheerio解析
  3. 将我们需要的信息保存下来,通过各种形式访问到这种信息
    建立fetch(文件对象),输入文件信息,fs /mysql模块写入

2.分析网站链接格式和网页信息格式

cheerio

在本次实验中,主要用到的功能如下:
1.解析HTML
首先需要手动加载html文档,使用的方式如下

   var cheerio = require('cheerio'),$ = cheerio.load('<ul id = "fruits">...</ul>');

2.选择器
cheerio选择器几乎和jQuery一模一样。它是文档遍历和操作的起点。
在本实验中,主要用到了以下几种选择器方法:
选取页面中所有的超链接。首先获取页面中所有标签,再遍历获取其href属性的值,具体的代码如下:

try {seedurl_news = $('a');} catch (e) { console.log('url列表所处的html块识别出错:' + e) };seedurl_news.each(function(){try {var href = "";href = $(this).attr('href'); //获取href属性}catch(e) {console.log('get the seed url err' + e);}}

按照指定class属性名称来进行选取

爬取新浪新闻

如下所示新浪新闻的链接格式

https://cul.news.sina.com.cn/topline/2021-04-13/doc-ikmyaawa9440823.shtml

https://cul.news.sina.com.cn/stickynews/2021-04-14/doc-ikmxzfmk6721643.shtml

https://cul.news.sina.com.cn/stickynews/2021-04-14/doc-ikmxzfmk6720347.shtml

可以看到基本的格式为/年-月-日/doc-8位字符7位数字.shtml

Javascript匹配规则如下

\d 匹配一个非负整数, 等价于 [0-9]

\s 匹配一个空白字符

\w 匹配一个英文字母或数字,等价于[0-9a-zA-Z]

. 匹配除换行符以外的任意字符,等价于[\n]

所以构造正则表达式为

var url_reg = /\/(\d{4})-(\d{2})-(\d{2})\/doc-(\w{8})(\d{7}).shtml/;

匹配时间规范化为年月日

var regExp = /((\d{4}|\d{2})(\-|\/|\.)\d{1,2}\3\d{1,2})|(\d{4}年\d{1,2}月\d{1,2}日)/

匹配规则为年份可以用四位数字或者两位数字来表示,中间的分隔符可以是- / .。\3是指引用前面的匹配,也即引用分隔符。也就是将如2021-04-1、2021/04/1、2021.04.1都转为2021年4月1日。

识别我们所要爬取的内容

由上图可以看到<meta name=“description” content="在这里,遇见更大更好的未来!“所以获取keywords的方式为var keywords_format = " $(‘meta[name=“keywords”]’).eq(0).attr(“content”)”;

var seedURL_format = "$('a')";
var keywords_format = " $('meta[name=\"keywords\"]').eq(0).attr(\"content\")";
var source_format = " $('meta[name=\"mediaid\"]').eq(0).attr(\"content\")";
var title_format = "$('meta[property=\"og:title\"]').eq(0).attr(\"content\")";
var date_format = "$('meta[property=\"article:published_time\"]').eq(0).attr(\"content\")";
var author_format = "$('meta[property=\"article:author\"]').eq(0).attr(\"content\")";
var desc_format = " $('meta[property=\"og:description\"]').eq(0).attr(\"content\")";
var content_format = "$('.article').text()";

如上图可以看到class为article所以获取正文的方式为var content_format = “$(’.article’).text()”;

爬取人民网新闻

网页链接格式如下

http://cpc.people.com.cn/n1/2021/0417/c164113-32080488.html

http://world.people.com.cn/n1/2021/0417/c1002-32080374.html

http://politics.people.com.cn/n1/2021/0417/c1001-32080356.html

可以看到格式为/年/月日/c至少4位数字-8位字符.html,所以构造正则表达式如下

var url_reg = /\/(\d{4})\/(\d{4})\/(\w{1})(\d{4,})-(\d{8}).html/;

识别我们所要爬取的内容

由上图可以看到<meta name=“author” content="105463"所以获取author的方式为var author_format = “$(‘meta[name=“author”]’).eq(0).attr(“content”)”;

var seedURL_format = "$('a')";
var keywords_format = " $('meta[name=\"keywords\"]').eq(0).attr(\"content\")";
var source_format = " $('meta[name=\"source\"]').eq(0).attr(\"content\")";var title_format =  "$('title').text()";
var date_format = "$('meta[name=\"publishdate\"]').eq(0).attr(\"content\")";
var author_format = "$('meta[name=\"author\"]').eq(0).attr(\"content\")";
var desc_format = " $('meta[name=\"description\"]').eq(0).attr(\"content\")";var content_format = "$('.rm_txt_con.cf').text()";

html中的class用空格分割,jquery用来匹配lclass就是要加.。所以这里匹配正文部分的代码为:

var content_format = "$('.rm_txt_con.cf').text()";

央视新闻爬取

网页链接格式如下

https://news.cctv.com/2021/04/23/ARTIcvjyoOUcK7qm83KjKgka210423.shtml?spm=C96370.PPDB2vhvSivD.EJHwg9t6FrM7.1

https://news.cctv.com/2021/04/18/ARTIC2yfewl0c1gNbHXWNicB210418.shtml?spm=C94212.P4YnMod9m2uD.ENPMkWvfnaiV.88

https://news.cctv.com/2021/04/18/ARTI513XcI88poP3HstaeZ2B210418.shtml?spm=C94212.P4YnMod9m2uD.ENPMkWvfnaiV.314

https://news.cctv.com/2021/04/14/ARTIkp2Di57750wzEbwuUYDf210414.shtml?spm=C94212.PZd4MuV7QTb5.Euuu2IJOvZIL.206

https://news.cctv.com/2021/04/17/ARTIpxJaxJMR9jWGctPnuIBe210417.shtml?spm=C96370.PPDB2vhvSivD.EZ4sRtXz56aB.6

可以看到格式为/年/月/日/30位字母和数组的组合.shtml,所以构造正则表达式如下

var url_reg = //(\d{4})/(\d{2})/(\d{2})/(\w{30}).shtml/

识别我们所要爬取的内容

var seedURL_format = "$('a')";
var keywords_format = " $('meta[name=\"keywords\"]').eq(0).attr(\"content\")";
var source_format = " $('meta[name=\"source\"]').eq(0).attr(\"content\")";
var title_format =  " $('meta[property=\"og:title\"]').eq(0).attr(\"content\")";
var date_format = "$('.info1').text()";
var author_format = " $('meta[name=\"author\"]').eq(0).attr(\"content\")";
var desc_format = " $('meta[property=\"og:description\"]').eq(0).attr(\"content\")";
var content_format = "$('.content_area').text()";

其中publish_date在之后需要进行特殊处理,取出|之后的日期部分,处理代码如下

var arr=fetch.publish_date.split("|");var trimLeft = /^\s+/fetch.publish_date=arr[1].replace(trimLeft,"").replace("年","-").replace("月","-").replace("日","");

网易新闻

https://www.163.com/news/article/G8MVPOON000189FH.html

https://www.163.com/news/article/G8MPODL30001899O.html

由上述链接易知网易新闻的链接规律,书写正则表达式

var url_reg = /news\/article\/(\w{16}).html/;

同样可以通过谷歌显示网页源代码功能分析所要获取内容的javascript表达形式,代码如下:

var seedURL_format = "$('a')";
var keywords_format = " $('meta[name=\"keywords\"]').eq(0).attr(\"content\")";
var source_format = " $('meta[property=\"twitter:creator\"]').eq(0).attr(\"content\")";
var title_format = "$('meta[property=\"og:title\"]').eq(0).attr(\"content\")";
var date_format = "$('meta[property=\"article:published_time\"]').eq(0).attr(\"content\")";
var author_format = "$('meta[name=\"author\"]').eq(0).attr(\"content\")";
var desc_format = " $('meta[name=\"description\"]').eq(0).attr(\"content\")";
var content_format = "$('.post_body').text()";

3.数据库设计

使用mysql数据库建表语句如下

CREATE TABLE `fetches2` (`id_fetches` int(11)  NOT NULL AUTO_INCREMENT,`url` varchar(200) DEFAULT NULL,`source_name` varchar(200) DEFAULT NULL,`source_encoding` varchar(45) DEFAULT NULL,`title` varchar(400) DEFAULT NULL,`keywords` varchar(200) DEFAULT NULL,`author` varchar(200) DEFAULT NULL,`publish_date` date DEFAULT NULL,`crawltime` datetime DEFAULT NULL,`content` longtext,`createtime` datetime DEFAULT CURRENT_TIMESTAMP,PRIMARY KEY (`id_fetches`),UNIQUE KEY `id_fetches_UNIQUE` (`id_fetches`),UNIQUE KEY `url_UNIQUE` (`url`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

新建一个mysql.js文件,在里面写上具体操作,然后在主爬虫程序中引入。

连接池创建

在代码中引入mysql模块,并编写数据库配置:

var mysql = require("mysql");
var pool = mysql.createPool({host: '127.0.0.1',user: 'root',password: 'root',database: 'crawl'
});

在本实验中,主要是对数据库进行查询和插入的操作,并无更新和删除操作。
这里的两个函数,用于操作有参数和无参数的情况。

有参数的情况:

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

无参数的情况

var 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); //事件驱动回调});}});
};

4.爬虫具体代码实现

此处以爬取新浪新闻为例

首先,定义全局常量:

var source_name = "新浪新闻";
var domain = 'https://news.sina.com.cn';
var myEncoding = "utf-8";
var seedURL = 'https://news.sina.com.cn/';

encoding格式需要根据网页链接特点调整,否则会出现写入数据库的数据是乱码的情况

接着,就是我们前面讲述的链接的正则表达式匹配以及获取页面内容

为防止爬虫被屏蔽,为爬虫写一个header,在爬取网页时假装设备访问

var headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.65 Safari/537.36'
}

定义request函数,调用该函数能够访问指定的url并且能够设置回调函数来处理得到的html页面。截取过程是异步完成的:

function request(url, callback) {var options = {url: url,encoding: null,//proxy: 'http://x.x.x.x:8080',headers: headers,timeout: 10000 //}myRequest(options, callback)
};

定义seedget函数,从种子页面抓取二级页面的url

function seedget() {request(seedURL, function(err, res, body) { //读取种子页面// try {//用iconv转换编码if(body==undefined)return;var html = myIconv.decode(body, myEncoding);//console.log(html);//准备用cheerio解析htmlvar $ = myCheerio.load(html, { decodeEntities: true });// } catch (e) { console.log('读种子页面并转码出错:' + e) };var seedurl_news;try {seedurl_news = eval(seedURL_format);} catch (e) { console.log('url列表所处的html块识别出错:' + e) };seedurl_news.each(function(i, e) { //遍历种子页面里所有的a链接var myURL = "";try {//得到具体新闻urlvar href = "";href = $(e).attr("href");// console.log(href);if (href == undefined) return;if (href.toLowerCase().indexOf('http://') >= 0||href.toLowerCase().indexOf('https://') >= 0) myURL = href; //http://开头的以及https://else if (href.startsWith('//')) myURL = 'http:' + href; 开头的else myURL = seedURL.substr(0, seedURL.lastIndexOf('/') + 1) + href; //其他// console.log(myURL);} catch (e) { console.log('识别种子页面中的新闻链接出错:' + e) }if (!url_reg.test(myURL)) return; //检验是否符合新闻url的正则表达式//console.log(myURL);var fetch_url_Sql = 'select url from fetches where url=?';var fetch_url_Sql_Params = [myURL];mysql.query(fetch_url_Sql, fetch_url_Sql_Params, function(qerr, vals, fields) {// if (vals!=null)return;// vals.length > 0if (vals.length>0) {console.log('URL duplicate!')} else newsGet(myURL); //读取新闻页面});});});
};

定义newsGet函数,传入的参数为二级页面URL,解析得到新闻的具体信息,包括title, publish_date, source_name, keywords, content等。其中fetch中存储的是在之前爬取信息的结构化存储:

function newsGet(myURL) { //读取新闻页面request(myURL, function(err, res, body) { //读取新闻页面//try {var html_news = myIconv.decode(body, myEncoding); //用iconv转换编码//console.log(html_news);//准备用cheerio解析html_newsvar $ = myCheerio.load(html_news, { decodeEntities: true });myhtml = html_news;//} catch (e) {    console.log('读新闻页面并转码出错:' + e);};console.log("转码读取成功:" + myURL);//动态执行format字符串,构建json对象准备写入文件或数据库var fetch = {};fetch.title = "";fetch.content = "";fetch.publish_date = (new Date()).toFormat("YYYY-MM-DD");//fetch.html = myhtml;fetch.url = myURL;fetch.source_name = source_name;fetch.source_encoding = myEncoding; //编码fetch.crawltime = new Date();if (keywords_format == "") fetch.keywords = source_name; // eval(keywords_format);  //没有关键词就用sourcenameelse fetch.keywords = eval(keywords_format);if (title_format == "") fetch.title = ""else fetch.title = eval(title_format); //标题if (date_format != "") fetch.publish_date = eval(date_format); //刊登日期console.log('date: ' + fetch.publish_date);if(fetch.publish_date == null) return;// fetch.publish_date =fetch.publish_date.substr(0,10);if(typeof(fetch.publish_time)=='string'){fetch.publish_date = regExp.exec(fetch.publish_date)[0];fetch.publish_date = fetch.publish_date.replace('年', '-')fetch.publish_date = fetch.publish_date.replace('月', '-')fetch.publish_date = fetch.publish_date.replace('日', '')fetch.publish_date = new Date(fetch.publish_date).toFormat("YYYY-MM-DD");}if (author_format == "") fetch.author = source_name; //eval(author_format);  //作者else fetch.author = eval(author_format);if (content_format == "") fetch.content = "";else fetch.content = eval(content_format).replace("\r\n" + fetch.author, ""); //内容,是否要去掉作者信息自行决定if (source_format == "") fetch.source = fetch.source_name;else fetch.source = eval(source_format).replace("\r\n", ""); //来源if (desc_format == "") fetch.desc = fetch.title;else{if(eval(desc_format)!=null)fetch.desc = eval(desc_format).replace("\r\n", "");}// else  //摘要// var filename = source_name + "_" + (new Date()).toFormat("YYYY-MM-DD") +//     "_" + myURL.substr(myURL.lastIndexOf('/') + 1) + ".json";// 存储json// fs.writeFileSync(filename, JSON.stringify(fetch));var fetchAddSql = 'INSERT INTO fetches(url,source_name,source_encoding,title,' +'keywords,author,publish_date,crawltime,content) VALUES(?,?,?,?,?,?,?,?,?)';var fetchAddSql_Params = [fetch.url, fetch.source_name, fetch.source_encoding,fetch.title, fetch.keywords, fetch.author, fetch.publish_date,fetch.crawltime.toFormat("YYYY-MM-DD HH24:MI:SS"), fetch.content];//执行sql,数据库中fetch表里的url属性是unique的,不会把重复的url内容写入数据库mysql.query(fetchAddSql, fetchAddSql_Params, function(qerr, vals, fields) {if (qerr) {console.log(qerr);}}); //mysql写入});
}

5.存储结果展示

央视新闻

新浪新闻


人民网


网易新闻

二、 网站搭建

搭建过程分为一下几个部分:

  1. 用express构建网站访问mysql
  2. 用表格显示查询结果及分页
  3. 前端优化
  4. 时间热度分析

1.用express构建网站访问mysql

使用express脚手架来创建一个网站框架。
在terminal中输入:express -e search_site
将之前写好的mysql.js拷贝到该文件夹下并在文件夹内cmd运行:npm install mysql --save将mysql包安装到该项目中,并且将依赖项保存进package.json里
在search_site文件夹内cmd运行npm install。提示0vulnerability即为安装成功,完成网站搭建。若出现vulnerability不为0可考虑换源(如淘宝源)安装。

2.显示查询结果

后端实现

以按关键词检索新闻的全文/关键词/标题中是否包含该词的后端为例。编写mysql语句判断前端勾选了全文/关键词/标题中的哪几项作为筛选项。

router.get('/news_get', function(request, response) {//sql字符串和参数var fetchSql = "select url,source_name,title,author,publish_date " +"from fetches where ";var end=false;if (request.query.title=="true"){if (!end){end=true;}else fetchSql+=" or"fetchSql+=" title like '%"+request.query.words + "%'";}if (request.query.keywords=="true"){if (!end){end=true;}else fetchSql+=" or"fetchSql+=" keywords like '%"+request.query.words + "%'";}if (request.query.content=="true"){if (!end){end=true;}else fetchSql+=" or"fetchSql+=" content like '%"+request.query.words + "%'";}fetchSql+=" order by publish_date DESC";fetchSql+=";";console.log(fetchSql);console.log("*****");mysql.query(fetchSql, function(err, result, fields) {if (err) throw err;console.log("*****");response.writeHead(200, {"Content-Type": "application/json"});response.write(JSON.stringify(result));response.end();});
});

前端实现

实现复选框查询

<form><br> <input type="text" name="title_text" class="search"><input class="form1" type="checkbox" >title<input class="form2" type="checkbox">keywords<input class="form3" type="checkbox">content<!-- <input type="date" name="publish_date" value="" /> --><input class="form-submit" type="button" value="search"></form>

获取复选框的勾选情况,如果没有勾选任何一个复选框给出提示。

 $(document).ready(function() {$("input:button").click(function() {var title=$('input.form1').is(":checked");var keywords=$('input.form2').is(":checked");var content=$('input.form3').is(":checked");if (title.valueOf()==false && keywords.valueOf()==false && content.valueOf()==false){alert("请至少选择一项作为搜索范围");return;}

实现直接通过html语言将后端获取的数据data以表格形式展示以及通过bootstraptable展示数据两种方式。这里展示用bootstraptable获取数据的代码。

  $.get('/news_get?title='+ title +'&keywords='+keywords+'&content='+content+  '&words='+words, function(data) {$("#record2").empty();var params ='/process_get?title='+title +'&keywords='+keywords+'&content='+content+  '&words='+words;$(function(){console.log(params);$("#record2").empty();$('#record2').bootstrapTable('hideLoading');$('#record2').bootstrapTable({url:params,method:'GET',pagination:true,sidePagination:'client',pageSize:5,striped : true,sortable : true,sortOrder:"asc",showRefresh:true,showLoading:false,// search:true,showToggle: true,toolbar: '#toolbar',showColumns : true,columns:[{field :'url',title : 'url',sortable : true}, {field:'title',title:'title'}, {field:'source_name',title:'source_name',sortable : true},{field:'author',title:'author'},{field:'publish_date',title:'publish_date',sortable : true}]})});

3.对查询结果进行分页

首先引入bootstrap自带的css

<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous"><link rel="stylesheet" href="https://unpkg.com/bootstrap-table@1.16.0/dist/bootstrap-table.min.css"><link rel="stylesheet" href="./stylesheets/search.css">

以及js

<script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script><script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script><script src="https://unpkg.com/bootstrap-table@1.16.0/dist/bootstrap-table.min.js"></script>

接着使用bootstraptable将输出的网页格式改为表格形式。

4.优化页面

可用如下网址调配各按钮的颜色

https://www.bestcssbuttongenerator.com/#/20

修改 input checkbox(复选框) 默认的背景颜色

 input[type=checkbox]{cursor: pointer;position: relative;width: 15px;height: 15px;font-size: 14px;
}input[type=checkbox]::after{position: absolute;top: 0;background-color: #dbe6c4;color: white;width: 15px;height: 15px;display: inline-block;visibility: visible;text-align: center;content: ' ';
}input[type=checkbox]:checked::after{content: "✓";font-size: 12px;font-weight: bold;
}

搜索框颜色修改

5.时间热度分析

返回每天对应关键词的搜索数量,在前端分别用表格以及echarts图的形式展示。

后端

router.get('/timehot', function(request, response) {//sql字符串和参数var fetchSql = "select publish_date,count(*) as num " +"from fetches where ";var end=false;if (request.query.title=="true"){if (!end){end=true;}else fetchSql+=" or"fetchSql+=" title like '%"+request.query.words + "%'";}if (request.query.keywords=="true"){if (!end){end=true;}else fetchSql+=" or"fetchSql+=" keywords like '%"+request.query.words + "%'";}if (request.query.content=="true"){if (!end){end=true;}else fetchSql+=" or"fetchSql+=" content like '%"+request.query.words + "%'";}fetchSql+=" group by publish_date ";fetchSql+=" order by publish_date ASC";fetchSql+=";";console.log(fetchSql);console.log("*****");mysql.query(fetchSql, function(err, result, fields) {if (err) throw err;console.log("*****");response.writeHead(200, {"Content-Type": "application/json"});response.write(JSON.stringify(result));response.end();});
});

前端

echarts图,首先构建画布。

<div id="main" style="width: 600px;height:400px;"></div><script type="text/javascript">// 基于准备好的dom,初始化echarts实例var myChart = echarts.init(document.getElementById('main'));

option中设置画图的数据

myChart.resize();
var option={//标题title:{text:'新闻时序图'},//工具箱//保存图片toolbox:{show:true,feature:{saveAsImage:{show:true}}},dataset: {// 提供一份数据。source:data},//图例-每一条数据的名字叫销量// legend:{//     data:['销量']// },//x轴xAxis: {type: 'category', gridIndex:0,axisLabel: {interval:0,rotate:15}},//y轴没有显式设置,根据值自动生成y轴yAxis:{type:'value', gridIndex:0},//数据-data是最终要显示的数据series:[{itemStyle : { normal: {label : {show: true}}},type:'line',encode:{x:'publish_date',y :'num'}}]};myChart.setOption(option);

6.结果展示

搜索结果页面展示


时间热度分析


额外分析每个数据源的新闻量对比

三、错误处理

1.TypeError [ERR_INVALID_ARG_TYPE]: 报错

  1. npm cache clean --force

  2. npm install

    清除缓存并重装依赖 问题解决

    如还不能解决 这个报错的意思是参数类型不断 先判断是否为string类型,只有当是string类型时才进行之后的操作

2.爬虫得到的数据出现中文乱码

将myEncoding由utf-8改为gbk即可。

3.MAC mysql密码输入正确的情况下报错

ERROR 1045 (28000): Access denied for user ‘root’@‘localhost’ (using password: YES)

参考配置链接:https://blog.csdn.net/qq1808814025/article/details/112236959

最简单直接的方法 重装mysql 一切解决

mysql修改密码 mysql> alter user ‘root’@‘localhost’ identified by ‘root’;

4.npm audit fix 解决方法

found 4 vulnerabilities (3 low, 1 critical) in 126 scanned packages

4 vulnerabilities require manual review. See the full report for details.

处理方法为换源,详见https://www.it610.com/article/1287669118148849664.htm

四、总结

本次项目完成了用nodejs爬取新闻网站,存入mysql数据库并使用express框架搭建网站并进行时间热度分析。熟悉了正则表达式以及如何从要爬取网站的源代码分析要爬取的内容应该如何获取,爬虫的基本结构以及工作原理,前后端数据传输,echarts画图前端的css优化,以及分页操作(虽然最后对于bootstrap的一直在加载数据加载不出来的问题没有能很好的解决。)

十分感谢老师和助教的答疑!

web编程项目--新闻网站搭建相关推荐

  1. mysql跳过安全_【Python安全攻防过渡篇:web编程和环境搭建】

    web编程 web编程不是说用python做web开发,而是用python与web交互.常用的模块有urlib,urlib2,这是python内置的模块. 同时,还有基于urlib的第三方库,比如re ...

  2. centos python_【Python安全攻防过渡篇:web编程和环境搭建】

    web编程 web编程不是说用python做web开发,而是用python与web交互.常用的模块有urlib,urlib2,这是python内置的模块. 同时,还有基于urlib的第三方库,比如re ...

  3. java web 实践项目(搭建web留言系统)

    声明:这是实践java的第二个项目,它主要包括以下知识: 前端:html css javascript 服务端: tomcat服务器,servlet ,jsp 后端:java 数据库:mysql 这个 ...

  4. IDEA搭建Web Service项目

    上篇小博记录了MyEclipse下搭建简单Web Service项目的详细过程,这篇将记录IDEA下,简单Web Service项目搭建的详细过程. 1.新建Web Service服务端项目,见下两图 ...

  5. web编程期中项目作业

    新闻爬虫与爬取结果的查询网站的实现 项目要求 一.爬虫部分 30分 1.完成最少一个目标网站(网站主题不限,不允许直接使用示例中的中国新闻网)的分析和爬虫设计. 2.爬取不少于100条数据(每条数据包 ...

  6. Java web小项目_个人主页(1)—— 云环境搭建与项目部署

    摘自:Java web小项目_个人主页(1)-- 云环境搭建与项目部署 作者:丶PURSUING 发布时间: 2021-03-26 23:59:39 网址:https://blog.csdn.net/ ...

  7. 初识JavaWeb(web开发概述、web开发环境的搭建、创建并发布web项目)

    文章目录 JavaWeb web开发概述 web开发环境的搭建 web服务器的选择 环境搭建 Tomcat的配置文件 创建发布Web项目 JavaWeb web开发概述 学习web开发, 我们需要一台 ...

  8. [Python]WEB编程--个人日记网站搭建(一)

    用Python+Tornado 编写一个个人日记网站(一) 讲道理,用惯了Flask感觉还是不熟悉Djongo,所以先来看一下Tornado(滑稽),记住这是一个最简单的最暴力的网页,毫无细节. 'F ...

  9. 学习(Java Web)编程技术要点及方向; 完成项目的要决

    本文亮点: 传统学习编程技术落后,应跟著潮流,要对业务聚焦处理. 要Jar, 不要War:以小为主,以简为宝,集堆而成. 去繁取简 Spring Boot,明日之春. 集堆综合技术如 jHipster ...

最新文章

  1. linux内核开机显示企鹅logo,批改linux内核kernel开机logo(小企鹅)
  2. hdu3001(三进制状压)
  3. php项目列表,php – 如何获取类似项目的列表
  4. 请交一个关于域的问题
  5. [vue-element] ElementUI使用表格组件时有遇到过问题吗?
  6. java 多线程 day06 threadLocal
  7. Deep Speaker代码解析
  8. 换回了WINDOWS7
  9. Keras:基于Python的深度学习库
  10. Xcode 5设置Deployment Target
  11. 23个可以免费学习编程的网站
  12. 【题解】LuoGu5369:[PKUSC2018]最大前缀和
  13. 对一张静态图片的识别
  14. aid learning安装应用_极致安卓—Termux/Aid Learning安装宇宙最强VS Code
  15. ☆【容斥原理】【SCOI2010】幸运数字
  16. 如何安装Eclipse WTP插件
  17. 微软个人云端服务器在哪里找,云端的服务器在哪里
  18. ZT——你怎么过河? -在CMM实践中你是否愿意多走1公里-软件工程 CMM与过程改进
  19. 哪一种编程语言适合人工智能
  20. Android Studio 类微信界面的制作

热门文章

  1. thinkphp6 + vue 整合验证码功能
  2. ONLY_FULL_GROUP_BY问题
  3. 使用for循环遍历数组
  4. 瑞萨开发记录04:按键控制数码管(R5F104FEA芯片)
  5. mysql提升事务性能
  6. 愿逝者安息,生者坚强
  7. 导入数据库出现错误:无权限。操作系统错误 5:“5(拒绝访问。)”。
  8. 必知 Oracle 数据字典
  9. 全球瞭望:中国最大的调查研究咨询公司排名
  10. 学习笔记TF038:实现估值网络