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

首先介绍一下爬虫所需要的的包
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()就是回调跳过
这哥可以解决批量下载图片时候出现的异常
node.js爬虫之下载图片,批量下载图片,控制下载图片并行上限_第1张图片


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

欢迎加群一起交流哦!
315552185

你可能感兴趣的:(node.js)