您的位置:首页 > Web前端 > Node.js

node.js爬虫之下载图片,批量下载图片,控制下载图片并行上限

2017-06-03 16:46 633 查看
首先介绍一下爬虫所需要的的包

require(“request”); –get post请求页面

require(“cheerio”) –解析文本对象为DOM对象 也就是说将string 装换为 js操作的 $() 这种选择器

require(‘fs’); – 保存文件到本地

require(“async”) –流程控制 主要是控制抓取时间间隔

require(‘mkdirp’); –创建文件夹

require(‘iconv-lite’); GBK UTF-8 转码

require(‘url’) –解析url成各种对象

require(‘path’); –处理文件路径

接下来是抓取图片的流程了

首先定义配置
var options = {
uri: 'http://www.xxxxxx.com/',
dir: './output/', //保存目录
downLimit: 2//图片并行下载上限
}

然后主程序检测图片下载完事件
/**
* 开始下载(程序入口函数)
*/
function start() {
//url地址 如果是的url是规律的分页 可以看我另外一个[爬斗鱼虎牙主播](http://blog.csdn.net/q3585914/article/details/72058261)
var opts = [
// 'htm_data/7/1705/2423174.html',
'htm_data/7/1705/2402955.html',
'htm_data/7/1705/2385537.html',
'htm_data/7/1705/2382263.html'
];
//串行抓取页面,就是一个一个抓,
async.forEachSeries(opts, function(opt, callback) {
//抓当个页面
parsePage(options.uri +opt, (err) => {callback()});
},function (err) {
if (err) {
console.log('error: %s'.error, err.message);
} else {
console.log('success: 下载完毕'.info);
}
});

}
//抓单个页面
function parsePage(url, callback) {
request({url: url, encoding: null}, function (error, response, body) {
if (!error && response.statusCode == 200) {
//由于页面是GBK 所以使用模块iconv来转码
var str = iconv.decode(body, 'gbk');
//将字符串装换为DOM
var $ = cheerio.load(str);
var links = [];
//分析图片url,由于使用了cheerio模块所以跟页面js一样分析
$(".do_not_catch .do_not_catch").find("img").each(function () {
var src = $(this).attr('src');
links.push(src);
});

// 创建目录
var title = $("title").text()
var newdir =options.dir+title.trim().replace(" - 技術討論區", "");
//创建目录,一个页面,一个目录
mkdir(newdir);
//下载图片
downImages(newdir,links,callback)

}
});

}

/**
* 创建目录
*/
function mkdir(title) {

console.log('准备创建目录:%s', title);
if (fs.existsSync(title)) {
console.log('目录:%s 已经存在'.error, title);

}else {
mkdirp(title, function (err) {
console.log('title目录:%s 创建成功'.info, title);
});
}
}

/**
* 下载图片列表中的图片
*/
function downImages(dir,links, callback) {
console.log('发现%d张图片,准备开始下载...', links.length);
//eachLimits 控制下载图片并行上限 第二个参数 options.downLimit 就是配置
async.eachLimit(links, options.downLimit,function (imgsrc,cb) {
var url = urldm.parse(imgsrc);
//获取url最后的名字
var fileName = path.basename(url.pathname);
//去掉/
var toPath = path.join(dir, fileName);
console.log('开始下载图片:%s,保存到:%s', fileName, dir);
//这个地方要详细说了
request(encodeURI(imgsrc)).on('error', function(err) {
cb();
}).pipe(fs.createWriteStream(toPath)).on('finish',()=>{
console.log('图片下载成功:%s', imgsrc);
cb();})
}, callback);

}


下载图片可以使用

request('http://google.com/doodle.png').pipe(fs.createWriteStream('doodle.png'))


但是如果图片下载和保存出错就会导出程序报错终止,所以需要加一个事件来控制

就是来监听error,他可以解决你保存时候出错问题 cb()就是回调跳过

这哥可以解决批量下载图片时候出现的异常



request(encodeURI(imgsrc)).on('error', function(err) {
cb();
}).pipe(fs.createWriteStream(toPath)).on('finish',()=>{
console.log('图片下载成功:%s', imgsrc);
cb();})


欢迎加群一起交流哦!

315552185
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息