项目需求
选取3-5个代表性的新闻网站(比如新浪新闻、网易新闻等,或者某个垂直领域权威性的网站比如经济领域的雪球财经、东方财富等,或者体育领域的腾讯体育、虎扑体育等等)建立爬虫,针对不同网站的新闻页面进行分析,爬取出编码、标题、作者、时间、关键词、摘要、内容、来源等结构化信息,存储在数据库中。
建立网站提供对爬取内容的分项全文搜索,给出所查关键词的时间热度分析。
新闻网站解析
网易新闻
这里所进行的爬虫详细步骤是以网易新闻为例。以此为例,可以爬取现在绝大多数新闻网站的具体新闻内容。
新闻页面解析
首先在head里面其实已经可以看到绝大多数的所需内容,这里已经包含了title、keywords、description、author:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jPXmBYZQ-1658504215576)(file://C:\Users\86189\AppData\Roaming\marktext\images\2022-07-22-21-46-22-image.png?msec=1658497582429)]
而关于剩下的正文阶段,则是继续在该html页面上寻找内容:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VWqHjtLV-1658504215578)(file://C:\Users\86189\AppData\Roaming\marktext\images\2022-07-22-21-48-17-image.png?msec=1658497697043)]
那么其实我们就可以根据获取到的页面内容进行相应的正则表达式的编写:
var seedURL_format = "$('a')";
var keywords_format = " $('meta[name=\"keywords\"]').eq(0).attr(\"content\")";
var title_format = "$('meta[property=\"og:title\"]').eq(0).attr(\"content\")";
var date_format = "$('.post_info').eq(0).text()";
var time_format = "$('input[id=\"newstime\"]').eq(0).attr(\"value\")"
var author_format = "$('input[id=\"editorname\"]').eq(0).attr(\"value\")";
var content_format = "$('.post_body').eq(0).text()";
var desc_format = " $('meta[name=\"description\"]').eq(0).attr(\"content\")";
var source_format = "$('#source_baidu').text()";
当然除了获取到相应的内容后,也需要对页面中的url进行相应的解析获取,当我把页面中所有的url输出后进行分析可以大概看出,排除掉一些相应的广告之后,获得了如下的正则匹配规则:
var url_reg = /https:\/\/www.163.com\/[a-z]{1,}\/article/;
当然这里不同的网站所对应的新网子网站url也是不一样的,如中国新闻网则是使用的年份进行的对应。
var url_reg = /http:\/\/www.chinanews.com.cn\/[a-z]{1,}\/2022/;
在构建好相应的正则匹配规则之后,便是编写相应的爬虫程序,当然这里主要使用的是request以及cheerio,在使用前执行相应的 n p m i n s t a l l npm\ install npm install即可。
数据库构建
在爬取到网站相应的源信息后,接下来便是将其存储到一个可供访问的空间中。当然这里也可以将其存储在本地,甚至以json文件存储。但是随着数量越来越多,存储在本地显然是不现实的,这里我们选择了使用mysql进行存储。
这里创建了一张名为news的表,共含有8个表项,分别为:id(新闻在数据库中的标识符)、url(新闻源地址)、source_name(新闻来源)、source_encoding(新闻编码格式)、title(新闻标题)、keywords(新闻关键词)、author(新闻作者)、publish_date(新闻出版时间)、content(新闻具体内容)。因为这里的id为自增属性,在插入时便只需记录其他七项数据即可。
当然可能会出现在有些新闻中是不存在的情况,这里只需要将部分必要的属性设置为非空即可。
CREATE TABLE `news` (
`id` int(100) NOT NULL AUTO_INCREMENT,
`url` varchar(255) NOT NULL,
`source_name` varchar(100) NOT NULL,
`source_encoding` varchar(30) NOT NULL,
`title` text NOT NULL,
`keywords` varchar(100) DEFAULT NULL,
`author` varchar(100) DEFAULT NULL,
`publish_date` date DEFAULT NULL,
`content` text,
PRIMARY KEY (`id`,`url`)
) ENGINE=InnoDB AUTO_INCREMENT=961 DEFAULT CHARSET=utf8;
网站构建
在准备好基本的源数据后,我们就可以对我们的源数据进行相应的建模使用。
网站基本结构
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-i0vLHrpm-1658504215578)(file://C:\Users\86189\AppData\Roaming\marktext\images\2022-07-22-13-54-07-image.png?msec=1658469247302)]
与绝大多数新闻的搜索网站类似,整体的页面布局还是较为简洁的,主要就是一个新闻搜索的输入框以及一个查询按钮,负责了主要功能。这里监听输入框中的内容,而查询按钮则是绑定了多个函数,以此来进行对数据库的查询以及结果的展示。
在网站的下面还展示了三个新闻网站的来源,并且可以通过直接跳转的方式,访问对应的三个新闻网站的主页面,以此获得更多的新闻内容。
搜索提示
对于现在绝大多数的新闻搜索引擎来说,系统的智能推荐功能也是一个相当重要的部分。为了实现这一功能,需要对输入框进行实时的监听,以此来进行实时的推荐。但因为这个对数据库的访问会产生的巨大压力,为此还做了数据库的主从热备。这里因为实时访问并不会对数据库产生写的过程,只有查询这一功能,所以做主从热备并没有较大的问题。
当然这里也可以通过将每日的热门新闻存储在本地,以此来加快对推荐的加载速度。进行一个相应的双保险推荐。
最后的结果展示如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3FvJ3zyy-1658504215579)(file://C:\Users\86189\AppData\Roaming\marktext\images\2022-07-22-14-46-16-image.png?msec=1658472376697)]
查询结果展示
这里对于查询逻辑的构建主要是按照标题进行的模糊化查询。
select * from news where title like '%params.title%'
而对于查询到的结果来说,首先是将日期、名称、作者、来源四个属性做成一个表格,并且对于日期与来源两列构成了一个可供排序的属性。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-d5oJ7fsd-1658504215579)(file://C:\Users\86189\Desktop\result.png?msec=1658502214385)]
而除了对于每条新闻的基本信息进行的表格呈现以外,还对表格中的每一项做了下拉菜单的详细展示,包括了关键词、原文链接等详细属性,这里可以使用原文链接进行直接跳转。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Sg8omzOO-1658504215580)(file://C:\Users\86189\AppData\Roaming\marktext\images\2022-07-22-22-42-31-image.png?msec=1658500951255)]
当然这里还遇到了一个问题是关于在下拉菜单中超链接的使用问题,在主页面的创建过程中,通过使用 h r e f href href标签便建构出了超链接
<a href="https://www.chinanews.com.cn/" target="_blank"> 中国新闻网 </a>
但是这里对于表格在vue框架中,首先要通过 s l o t − s c o p e slot-scope slot−scope插槽进行遍历,紧接着在使用超链接时还需要在 h r e f href href前加上:,不然会跳转到 h t t p : / / 8080 / 原文链接 http://8080/原文链接 http://8080/原文链接 的url去,而不是相应的超链接。
<el-link :href="props.row.url" target="_blank">
{{ props.row.url }}
</el-link>
关键词热度分析
这里是对于用户搜索的关键词进行时间热度分析。因为在爬虫的数据库中,我们将文章的出版日期进行了相应的存储,并将其格式统一成了xxxx-xx-xx的形式。这里因为其日期格式在数据库中的统一,其实只要对其按照某一特定属性进行COUNT即可(这里是以标题为例)。
SELECT publish_date,COUNT(*)
FROM (SELECT * FROM news
WHERE title LIKE '%" + params.title + "%') as tmp GROUP BY publish_date;
而在查询到其在数据库之中的日期以及相应的篇数,就可以根据返回的信息,即出版日期对应的相对查询数量,这样与之对应的便是在echarts中对应的x轴与y轴。
let option = {
title: {
show: true,
text: '关键词"' + this.input + '"出现频次',
},
xAxis: {
type: "category",
data: this.dates,
}, //X轴
yAxis: {
type: "value"
}, //Y轴
series: [{
data: this.values,
type: "line"
}], //配置项
};
this.chart.setOption(option);
最后折线图可视化如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VaB3cIGW-1658504215580)(file://C:\Users\86189\AppData\Roaming\marktext\images\2022-07-22-21-14-21-image.png?msec=1658495661122)]
项目Github地址: