文章目录
一、新闻爬取
一共选了四个新闻网站进行爬虫,分别是人民网、新浪新闻、网易新闻、央视新闻,其中主要爬取的网站是人民网和新浪新闻(爬取多天数据、总数据量达1360条)并且将爬取结果存储在mysql中。
上demo
新闻网站demo|时间热度分析
1.爬虫原理
- 首先我们搜索主页面,获取我们想要的子网页的URL
通过request请求,cheerio解析,each遍历 - 搜索出我们子网页页面中我们需要的信息:标题,正文等
通过request请求,cheerio解析 - 将我们需要的信息保存下来,通过各种形式访问到这种信息
建立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