这几天,心血来潮,想学一下爬虫,本来想使用,python的scrapy的,但是。。。但是。。。折腾了一天,都没折腾好环境,就不折腾了,果断投奔nodejs的cheerio去。
cheerio,就是nodeJs服务端的jquery。对于原生渣渣的我,这个实在是太方便了。立马找了一个小案例:
var express = require('express');
var cheerio = require('cheerio');
var superagent = require('superagent');
var app = express();
app.get('/', function (req, res, next) {
superagent.get('https://cnodejs.org/')
.end(function (err, sres) {
if (err) {
return next(err);
}
var $ = cheerio.load(sres.text);
var items = [];
$('#content .header a').each(function(index, el) {
var $element = $(el);
items.push({
title: $element.text()
});
});
res.send(items);
});
});
app.listen(3000, function () {
console.log('app is listening at port 3000');
});
浏览器完美访问。结果如下
[
{
"title": "全部"
},
{
"title": "精华"
},
{
"title": "分享"
},
{
"title": "问答"
},
{
"title": "招聘"
}
]
,然后自己去一样画葫芦抓取其他的网站,因为平时下片都是从www.dy2018.com下的,然后就拿其开刀:
var express = require('express');
var cheerio = require('cheerio');
var superagent = require('superagent');
charset(superagent);
var app = express();
var url = 'http://www.dy2018.com';
app.get('/', function (req, res, next) {
superagent
.get(url)
.end(function (err, sres) {
if (err) {
return next(err);
}
var $ = cheerio.load(sres.text, {decodeEntities: false});
var items = [];
var url_prefix = url;
$('.co_area2').eq(0).find('li a').each(function(index, el) {
var $element = $(el);
items.push({
title: $element.text(),
url: url_prefix + $element.attr('href')
});
});
res.send(items);
});
});
app.listen(3000, function () {
console.log('app is listening at port 3000');
});
也能跑起来,但是,中文乱码了。因为dy2018的编码是gb2312,再折腾了一下,才知道在使用superagent的时候,只支持utf-8的,这就导致了悲剧的发生。解决方案,有很多我采取使用superagent-charset的方案。代码如下:
var express = require('express');
var cheerio = require('cheerio');
var charset = require('superagent-charset');
var superagent = require('superagent');
charset(superagent);
var app = express();
var url = 'http://www.dy2018.com';
app.get('/', function (req, res, next) {
superagent
.get(url)
.charset('gb2312')
.end(function (err, sres) {
if (err) {
return next(err);
}
var $ = cheerio.load(sres.text, {decodeEntities: false});
var items = [];
var url_prefix = url;
$('.co_area2').eq(0).find('li a').each(function(index, el) {
var $element = $(el);
items.push({
title: $element.text(),
url: url_prefix + $element.attr('href')
});
});
res.send(items);
});
});
app.listen(3000, function () {
console.log('app is listening at port 3000');
});
结果:
[
{
"title": "2015年贾樟柯导演剧情片《山河故人》BD国语中字",
"url": "http://www.dy2018.com/i/96180.html"
},
{
"title": "2016年美国6.4分喜剧家庭片《欢闹父子情/确认》BD中英双字",
"url": "http://www.dy2018.com/i/96918.html"
},
{
"title": "2016年美国7.6分喜剧运动片《飞鹰艾迪/飞跃奇迹》BD中英双字",
"url": "http://www.dy2018.com/i/96915.html"
},
{
"title": "2016年美国6分动作犯罪片《白宫沦陷2:伦敦沦陷》HD国语中字",
"url": "http://www.dy2018.com/i/96914.html"
},
{
"title": "2015年韩国6.1分古装爱情片《朝鲜魔术师》BD韩语中字",
"url": "http://www.dy2018.com/i/96913.html"
},
{
"title": "2016年美国7.5分动作战争片《危机13小时》BD中英双字",
"url": "http://www.dy2018.com/i/96912.html"
},
{
"title": "2016年邓超罗志祥喜剧奇幻片《美人鱼》BD国粤双语中字",
"url": "http://www.dy2018.com/i/96758.html"
},
{
"title": "2016年陈晓秦岚剧情爱情片《睡在我上铺的兄弟》HD中英双字",
"url": "http://www.dy2018.com/i/96909.html"
},
{
"title": "2016年白敬亭郭姝彤爱情片《谁的青春不迷茫》HD中英双字",
"url": "http://www.dy2018.com/i/96907.html"
},
{
"title": "2016年印度恐怖片《亡界之门/鬼门开》BD中英双字",
"url": "http://www.dy2018.com/i/96906.html"
},
{
"title": "2016年英国6.6分喜剧动作片《王牌贱谍:格林斯比》BD中英双字",
"url": "http://www.dy2018.com/i/96905.html"
},
{
"title": "2016年迪士尼高分冒险动画片《疯狂动物城》BD国英双语双字",
"url": "http://www.dy2018.com/i/96878.html"
},
{
"title": "2016年美国6.2分悬疑犯罪片《曼哈顿夜曲》BD中英双字",
"url": "http://www.dy2018.com/i/96900.html"
},
{
"title": "2016年张翰赵丽颖喜剧爱情片《女汉子真爱公式》HD中英双字",
"url": "http://www.dy2018.com/i/96898.html"
},
{
"title": "2016年英国科幻恐怖片《杀戮指令/杀戮命令》BD中英双字",
"url": "http://www.dy2018.com/i/96897.html"
}
]
完美,关键代码是使用superagent-charset,它的github源码地址https://github.com/magicdawn/superagent-charset
还有一个地方就是var $ = cheerio.load(sres.text, {decodeEntities: false}); cheerio加载的时候,要设置{decodeEntities: false}。
本文的demo地址:https://git.oschina.net/xbuding/nodejs_cheerio.git
app2.js是抓取电影天堂的demo