最近老师布置了个作业,要我们用爬虫爬取新闻并展示出来,因为我不会Python,网上查阅资料发现nodejs做的爬虫也不差,所以就用自己顺手的js来写一个乞丐版的爬虫吧...,我打算爬一下隔壁学校的新闻网页作为案例,网站地址为:http://www.dgut.edu.cn/dgut/ggyw/news_list.shtml
安装环境
1.在本机上运行nodejs需要安装nodejs环境,环境很容易装,直接在官网下载并安装就可以了不会的也可以看看教程。安装node之后npm(node包管理工具)会随着node一起安装起来,我们用控制台安装node模块的时候会用到。
2.检查是否安装完成,在电脑(我用的是windows)的控制台输入node -v,若弹出版本号则说明安装成功。
搭建项目
要知道node.js是一个模块化程度很高的语言,简单的说就是它本身只自带少部分模块,然后你有什么样的功能需求就安装什么样的模块。
在这个爬虫中,我们主要用到三个模块:
1、request,这个模块看名字就知道了是用来请求网页的。
2、cheerio,这个模块的用来解析网页的dom结构的,用法和jquery非常相似。
3、mysql,最后这个模块也很明显是用来连接mysql数据库的。
介绍完这些,我们下面就开始搭建项目文件:
首先在桌面新建一个文件夹(我命名为pachong),然后进控制台cd到这个文件夹下。
我们先初始化这个文件夹,也就是在控制台中继续输入npm init,然后一路回车就可以了,完成后我们的项目文件夹里面就会出现一个package.json的文件,这个是记录我们的项目的依赖的文件。
然后继续在这个文件夹下安装刚刚说的那三个模块,也就是在控制台中继续输入npm install request cheerio mysql
安装完成后我们打开刚刚新建的文件夹就可以看到又多出来了一个node_modules的文件夹,然后把文件夹拖进编辑器(我用的是vscode)里面,再自己新建一个js文件,我命名为pachong.js. 我的文件目录如下
至此我们的项目就搭建完成了,接下来就可以在pachong.js里面撸代码了。
编写爬虫
首先引入需要的模块:
const request=require("request")
const cheerio=require("cheerio")
const mysql=require('mysql')
然后创建数据库连接池,方便等下把数据存入数据库:按照下面的提示输入你的数据库信息
const db=mysql.createPool({host:'数据库地址',user:'账号',password:'密码',database:'数据库名'});
接着用request向网页发起请求,这里我们向东莞理工的新闻网http://www.dgut.edu.cn/dgut/ggyw/news_list.shtml发起请求,写出结构,我们就可以再else{}里面进行我们的操作了,先解析网页提取需要的信息,然后存入数据库。
request('http://news.dgut.edu.cn/dgut/xydt/news_list.shtml',function(err,res){
if(err)
{
console.log('请求出错');
}
else
{
}
在else{}里面先加一句:
var $ = cheerio.load(res.body, {decodeEntities: false});
这句话是初始化目标网页的dom结构的意思,decodeEntities false可以保持中文编码。可以简单的理解为把网页的结构都提取出来装载进$。
分析网页
我们要爬取的内容界面在这里,主要爬取标题、日期、和新闻链接
然后再看看网页源码,找到对应的部分:
看网页源码我们可以发现,我们所需要的信息分别是:
类名为listList的div下的<a>标签的href的值以及<a>标签所包裹的内容
以及<span>标签所包裹的内容
提取信息
接下来我们就可以用cheerio来提取网页的信息了,刚刚也说了它的用法和jQuery非常相似,有不会的地方基本上能看jquery文档解决。
直接上代码:
$('.listList').children('ul').children('li').each(function(){ //找到li元素对象然后通过each遍历
var newsTitle = $(this).children('a').text(); //得到<a>标签的文字
var newsTime= $(this).children('span').text();//得到<span>标签的文字
var newsUrl= "http://news.dgut.edu.cn"+$(this).children('a').attr('href');//得到<a>标签的href的值
})
newsUrl这里说明一下,我们爬到的href的值是这样的
/dgut/ggyw/201805/5562bb5b1c2049aebf6d95c8e2a80c7e.shtml
而实际上能访问到具体页面的url是这样的
http://www.dgut.edu.cn/dgut/ggyw/201805/5562bb5b1c2049aebf6d95c8e2a80c7e.shtml
所以我们手动加上一个http://www.dgut.edu.cn,到时候爬下来就可以用了
到了这一步我们已经完成了数据的获取,接下来存入数据库就OK了(记得先在数据库创建一张表),很简单,直接上代码吧
db.query(`INSERT INTO news (newsTitle, newsTime, newsUrl) VALUE(${newsTitle}', '${newsTime}','${newsUrl}')`,function(err,data){
if(err)
{
console.log("数据库连接错误");
}
这样就大功告成了,我还在代码里面加了提示语句,来显示爬取进度
item++;
console.log("已爬取"+item+"条记录");
最后我们来跑起来这个爬虫
打开控制台 cd到当前目录下 输入node pachong 点击回车
很开心看到这样的画面,我们再打开数据库看看
网页的15条记录都在,那么接下来就可以爬这个网址的所有记录了
观察一下URL,可以发现一定的规律,然后写个for循环就bingo了~,我就不再多写了,自己思考动手收获更大。
最后贴上完整代码
const request=require("request")
const cheerio=require("cheerio")
const mysql=require('mysql')
const db=mysql.createPool({host:'120.79.5554',user:'root',password:'root',database:'pachong'});
var item=0;
request('http://news.dgut.edu.cn/dgut/xydt/news_list.shtml',function(err,res){
if(err)
{
console.log('请求出错');
}
else
{
var $ = cheerio.load(res.body, {decodeEntities: false});
$('.listList').children('ul').children('li').each(function(){ //找到li元素对象然后通过each遍历
var newsTitle = $(this).children('a').text(); //得到<a>标签的文字
var newsTime= $(this).children('span').eq(1).text();//得到第二个<span>标签的文字
var newsUrl= "http://news.dgut.edu.cn"+$(this).children('a').attr('href');//得到<a>标签的href的值
db.query(`INSERT INTO news (newsTitle, newsTime, newsUrl) VALUE('${newsTitle}', '${newsTime}','${newsUrl}')`,function(err,data){
if(err)
{
console.log("数据库连接错误");
}
})
item++;
console.log("已爬取"+item+"条记录");
});
}
});