Node.JS 妹子图爬虫(2)

546 查看

读取本地数据

在上一篇中,我们已经将所有的url均保存在了json文件中,这里我们需要打开JSON文件并反序列化

var fs= require('fs');
var dirname = '/Users/wz/Desktop/'+'妹子图全'+'.json';
var data=JSON.parse(fs.readFileSync(dirname));

爬取具体图片的方法

由于这个网站的图片,每一页只有一张
要爬取一个图集,首先要知道有多少个页面

function get_max_number(url,callback) {
    superagent
        .get(url)
        .set('Connection','close')
        .set('User-Agent','Paw/2.1 (Macintosh; OS X/10.11.6) GCDHTTPRequest')
        .set('Host', 'www.mzitu.com')
        .end(function (err, sres) {
            // 常规的错误处理
            if (err) {
                console.error(err)
            }
            var $ = cheerio.load(sres.text);
            var $element = $('body > div.main > div.content > div.pagenavi').find('a').last().prev()
            var max = $element.attr('href').split('/').pop()
            callback(max)
        });
}

接下来我们通过URL下载图片

function download_img(uri, path, filename, callback){
    request.head(uri, function(err, res, body){
        // console.log('content-type:', res.headers['content-type']);  //这里返回图片的类型
        // console.log('content-length:', res.headers['content-length']);  //图片大小
        if (err) {
            console.log('err:'+ err);
            downloadImg(uri, path, filename ,callback);
            return false;
        }
        fixname = path.basename(uri).split('.').pop()
        var file = path + filename + '.' + fixname
        if(fs.existsSync(file)) {
            console.log('文件已存在:'+file)
            callback()
        }else{
            request(uri).pipe(fs.createWriteStream(file)).on('close', callback);  //调用request的管道来下载到 images文件夹下
        }
    });
};

需要考虑的问题
如果爬取异常终止,我们如何恢复工作?
这里我采用的方法了最简单的办法--检测文件夹是否存在,若存在则不下载
我们每个图集的子文件名为图集id号

图集下载

函数原型function load_girl_image(url_base,dir_base,callback)

function load_girl_image(url_base,dir_base,callback) {
    var dir_path = dir_base + url_base.split('/').pop()
    var folder_exists = fs.existsSync(dir_path);
    if (folder_exists) {
        console.log(dirpath + '存在')
        callback()
        return
    }else{
        get_max_number(url_base,function (max) {
            var index = 1
            var downloaded = 0
            while (index <= max){
                if (index != 1) url = url_base +'/'+ String(index)
                else url = url_base
                index ++;
                console.log('开始抓取 '+ url)

                superagent
                    .get(url)
                    .set('Connection','close')
                    .set('User-Agent','Paw/2.1 (Macintosh; OS X/10.11.6) GCDHTTPRequest')
                    .set('Host', 'www.mzitu.com')
                    //.charset('gb2312')
                    .end(function (err, sres) {
                        // 常规的错误处理
                        if (err) {
                            return //next(err);
                        }
                        var $ = cheerio.load(sres.text);
                        var data = $('body > div.main > div.content > div.main-image > p > a > img');
                        var title = $('body > div.main > div.content > h2').text()
                        var image_url = data.attr('src')

                            var title = title.replace(' ','')
                            var folder_exists = fs.existsSync(dir_path);
                            if (!folder_exists) fs.mkdir(dir_path);
                            download_img(image_url,dirpath + '/',title,function () {
                                console.log('完成'+title)
                                downloaded++
                                if (downloaded == max) callback()
                            })

                    });
            }
        })
    }
}

开始抓取

var target = 10000
function catchImage(items,begin,offset){
    load_girl_image(items[begin+offset].url,'/Users/xx/Desktop/mzt/',function () {
        if (offset < target&&begin+offset<items.length) {
            catchImage(items,begin,offset+1);
        }
    })
}
var fs= require('fs');
var dirname = '/Users/wz/Desktop/'+'妹子图全'+'.json';
var data=JSON.parse(fs.readFileSync(dirname));
catchImage(data,0,0);