为什么选择利用node来写爬虫呢?就是因为cheerio这个库,全兼容jQuery语法,熟悉的话用起来真真是爽
cheerio: Node.js 版的jQuery
http:封装了一个HTPP服务器和一个简易的HTTP客户端
iconv-lite:解决爬取gb2312网页出现乱码
既然是要爬取网站内容,那我们就应该先去看看网站的基本构成
选取的是电影天堂作为目标网站,想要去爬取所有最新电影的下载链接
页面结构如下:
我们可以看到每个电影的标题都在一个<a href="//m.sbmmt.com/wiki/164.html" target="_blank">class</a>
为ulink
的a
标签下,再往上定位,我们可以看到最外部的盒子class
为co_content8
ok,可以开工了
首先引入依赖,并设定需要爬取的url
var cheerio = require('cheerio'); var http = require('http'); var iconv = require('iconv-lite'); var url = 'http://www.ygdy8.net/html/gndy/dyzz/index.html';
核心代码 index.js
http.get(url, function(sres) { var chunks = []; sres.on('data', function(chunk) { chunks.push(chunk); }); // chunks里面存储着网页的 html 内容,将它zhuan ma传给 cheerio.load 之后 // 就可以得到一个实现了 jQuery 接口的变量,将它命名为 `$` // 剩下就都是 jQuery 的内容了 sres.on('end', function() { var titles = []; //由于咱们发现此网页的编码格式为gb2312,所以需要对其进行转码,否则乱码 //依据:“<meta http-equiv="Content-Type" content="text/html; charset=gb2312">” var html = iconv.decode(Buffer.concat(chunks), 'gb2312'); var $ = cheerio.load(html, {decodeEntities: false}); $('.co_content8 .ulink').each(function (idx, element) { var $element = $(element); titles.push({ title: $element.text() }) }) console.log(titles); }); });
运行node index
结果如下
成功获取电影title,那如果我想获取多个页面的title呢,总不可能一个一个url去改吧。这当然有办法,请往下看!
核心代码 index.js
var index = 1; //页面数控制 var url = 'http://www.ygdy8.net/html/gndy/dyzz/list_23_'; var titles = []; //用于保存title function getTitle(url, i) { console.log("正在获取第" + i + "页的内容"); http.get(url + i + '.html', function(sres) { var chunks = []; sres.on('data', function(chunk) { chunks.push(chunk); }); sres.on('end', function() { var html = iconv.decode(Buffer.concat(chunks), 'gb2312'); var $ = cheerio.load(html, {decodeEntities: false}); $('.co_content8 .ulink').each(function (idx, element) { var $element = $(element); titles.push({ title: $element.text() }) }) if(i < 2) { //为了方便只爬了两页 getTitle(url, ++index); //递归执行,页数+1 } else { console.log(titles); console.log("Title获取完毕!"); } }); }); } function main() { console.log("开始爬取"); getTitle(url, index); } main(); //运行主函数
结果如下
如果是人工操作,我们需要一次操作,通过点击进入电影详情页才能找到下载地址
那我们通过node如何来实现呢
常规先来分析页面布局
我们如果想要准确定位到下载链接,需要先找到id
为Zoom
的p,下载链接就在这个p
下的tr
下的a
标签内。
那我们就再定义一个函数,用于获取下载链接
getBtLink()
function getBtLink(urls, n) { //urls里面包含着所有详情页的地址 console.log("正在获取第" + n + "个url的内容"); http.get('http://www.ygdy8.net' + urls[n].title, function(sres) { var chunks = []; sres.on('data', function(chunk) { chunks.push(chunk); }); sres.on('end', function() { var html = iconv.decode(Buffer.concat(chunks), 'gb2312'); //进行转码 var $ = cheerio.load(html, {decodeEntities: false}); $('#Zoom td').children('a').each(function (idx, element) { var $element = $(element); btLink.push({ bt: $element.attr('href') }) }) if(n < urls.length - 1) { getBtLink(urls, ++count); //递归 } else { console.log("btlink获取完毕!"); console.log(btLink); } }); }); }
再次运行 node index
就这样我们将3个页面内所有电影的下载链接获取完毕,是不是很简单?
我们讲这些数据爬取出来当然是要进行保存的啊,在这里我选用了MongoDB来对其进行保存处理
数据保存函数 save()
function save() { var MongoClient = require('mongodb').MongoClient; //导入依赖 MongoClient.connect(mongo_url, function (err, db) { if (err) { console.error(err); return; } else { console.log("成功连接数据库"); var collection = db.collection('node-reptitle'); collection.insertMany(btLink, function (err,result) { //插入数据 if (err) { console.error(err); } else { console.log("保存数据成功"); } }) db.close(); } }); }
这里的操作很简单,就没必要上mongoose啦
再次运行 node index
这个Node.js实现的爬虫就是这样了,祝大家能爬到自己想要的数据;)
以上是使用Node.js实现简易爬虫的方法的详细内容。更多信息请关注PHP中文网其他相关文章!