nodejsではasyncを使って非同期操作を同期し、複数の非同期同時起動による接続エラーを避ける.

4954 ワード

/*
   nodejs                ,                 。
            ,          request,        (       )
           ,        ,asyn          
 */
const url = require('url');
const request = require('request');
const http = require('http');
const fs = require('fs');
const util = require('util');
const async = require('async');

function getUrl(id, arr) {
    var arrs = [];
    for (var i = 0; i < arr[1]; ++i) {
        var n = i + '';
        if (n !== '0') {
            while (n.length < 3) {
                n = 0 + n;
            }
        }
        var r = util.format('http://img.zngirls.com/gallery/%d/%d/%s.jpg', id, arr[0], n);
        arrs.push(r);
    }

    //console.log(arrs);
    return arrs;
}

function direct_download(_url, filename, cb) {
    var arrPath = filename.split('/');
    if (arrPath.length > 1) {
        var fullPath = '';
        arrPath = arrPath.slice(0, -1);
        do {
            fullPath += arrPath.shift() + '/';
            if (!fs.existsSync(fullPath)) {
                fs.mkdir(fullPath);
            }
        } while (arrPath.length > 0);
    }

    var opt = {
        proxy: 'http://proxy3.bj.petrochina:8080',
        url: _url,
        headers: {
            referer: 'http://www.baidu.com',
        }
    }

    request.get({
        proxy: 'http://proxy3.bj.petrochina:8080',
        url: _url,
        headers: {
            referer: 'http://www.baidu.com',
        }
    }).pipe(fs.createWriteStream(filename)).on('close', function () {
        console.log("       ");
        if (cb) {
            cb(null, "successful !");
            //callback      ,                result,result     
        }
    });
    //download(_url, filename);

    /*
     request.get(opt, function(err,res, body){
     if(err){
     console.log(err);
     console.log("          ...");
     }else{
     fs.writeFile(filename, body, function(err){
     if(err){
     console.log(err);
     console.log("          ...");
     }else{
     console.log("       ");
     if(cb){
     cb(null,"successful !");
     //callback      ,                result,result     
     }
     }
     });
     }
     });
     */
}

function download(ur, fileName) {
    //    (    )     (IO    )
    var u = url.parse(ur);
    var options = {
        //     
        host: 'proxy3.bj.petrochina',
        port: 8080,

        path: ur,
        //     ,       
        //headers : {Referer:'http://www.baidu.com',}
        headers: {
            Referer: 'http://www.baidu.com',
            Accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
            'Accept-Encoding': 'gzip, deflate, sdch',
            'Accept-Language': 'zh-CN,zh;q=0.8,en;q=0.6',
            Host: 't1.zngirls.com',
            'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36',
        }
    };

    http.get(options, function (res) {
        //        ,        ,       
        //      
        var fd = fs.openSync(fileName, 'w');

        //      
        res.on('data', function (chunk) {
            fs.writeSync(fd, chunk, 0, chunk.length);
            //console.log(util.inspect(chunk,true));
        });

        //      
        res.on('end', function () {
            fs.closeSync(fd);
            console.log(`save to ${fileName}`);
        });

    });
}

function somany_request() {
    var id = 18071;
    //var gallery = [[18812, 49], [19695, 49], [19019, 43], [18214, 49], [16751, 54], [13207, 72], [13206, 68]];
    var gallery = [[18812, 49], [19695, 49], [19019, 43], [18214, 49], [16751, 54], [13207, 72], [13206, 68]];
    var pictures = []
    gallery.forEach(function (i) {
        var urls = getUrl(id, i);
        urls.forEach(function (_url) {
            var filename = _url.split('/').slice(-4).join('/');
            pictures.push({url: _url, filename: filename});
            //direct_download(_url, filename);
        });
    });

    //        
    async.mapLimit(pictures, 10, function (pic, cb) {
        console.log('   10         ...');
        direct_download(pic.url, pic.filename, cb);
    }, function (err, result) {
        if (err) {
            console.log(err);
        } else {
            console.log('        ');
        }
    });
}

somany_request();
//direct_download('http://img.zngirls.com/gallery/18071/18812/0.jpg', 'gallery/18071/18812/0.jpg');