async太好用了,用了两个小时写的代码

/*
 从5442网站上把所有的热门推荐下载下来 async+cheerio+request
 */
const util = require('util');
const request = require('request');
const http = require('http');
const fs = require('fs');
const cheerio = require('cheerio');
const async = require('async');
const mkdirp = require('mkdirp');

function Picture5442() {
    this.host = 'http://www.5442.com/meinv/';
}

Picture5442.prototype = {
    main: function () {
        var self = this;

        async.auto({
            //如果是对象,需要进行绑定,否则this没有
            readIndex: self.readIndex.bind(self),
            downloadHot: ['readIndex', self.downloadHot.bind(self),],
        }, function (err, result) {
            if (err) {
                console.error(err);
            } else {
                //console.log(util.inspect(result, true));
                console.log('所有的任务都完成');
            }
        });
    },

    //从主页读取要下载的内容
    readIndex: function (callback) {
        request(this.host, function (err, res, body) {
            if (!err && res.statusCode == 200) {
                var $ = cheerio.load(body);
                var links = $('div.lists.listNum.listTime.listLine a');
                var linkArr = [];
                links.each(function (i) {
                    linkArr[i] = $(this).attr('href');
                });

                //console.log('links=', util.inspect(linkArr,true));
                linkArr.push('http://www.5442.com/meinv/20140802/11261.html');
                linkArr.push('http://www.5442.com/meinv/20140705/10361.html');
                callback(null, linkArr);
            } else {
                callback(err);
            }
        });
    },

    //下载所有热门
    downloadHot: function (result, callback) {
        var self = this;
        var urls = result.readIndex;
        if (urls.length < 1) {
            callback('没有有效链接,读取失败', null);
            return;
        }

        async.auto({
            getAllFirstImage: self.getAllFirstImage.bind(self, urls),
            downloadImages: ['getAllFirstImage', self.downloadImages.bind(self)],
        }, function (err, results) {
            console.log('所有的热门图片已经下载完成');
            callback();
        });
    },

    //下载一个影集
    downloadGallery: function (aurl, callback) {
        //使用while循环,直到下载不到正确的结果的时候就退出循环
        if(!aurl){
            callback();
        }

        var nexturl = aurl;
        var parentcb = callback;
        var dirname;
        var m = aurl.match(/^http:\/\/.+\/(.+\/.+\/.+)\/(\d+\.jpg)/);
        if (!m) {
            callback('无效url地址,无法解析:' + aurl, null);
        } else {
            dirname = m[1];
        }

        async.auto(
            {
                init: function (callback) {
                    //创建目录结构
                    if (!fs.existsSync(dirname)) {
                        mkdirp(dirname, function (err) {
                            if (err) {
                                console.error(err);
                                parentcb(err, null);
                                return;
                            } else {
                                console.log('创建目录成功:' + dirname);
                                callback();
                            }
                        });
                    } else {
                        //不需要创建目录
                        callback();
                    }
                },

                work: ['init', function (result, callback) {
                    var flagExit = false;
                    async.during(
                        function (callback) {
                            callback(null, !flagExit);
                        },
                        function (callback) {
                            console.log('开始下载:' + nexturl);
                            //request.get(nexturl).pipe()
                            http.get(nexturl, function (res) {
                                var chunks = [];
                                if (res.statusCode !== 200) {
                                    //退出循环
                                    console.error('下载图片失败,认为已经没有可以下载的图片了:' + nexturl);
                                    flagExit = true;
                                    //直接调用回调函数退出,避免重复回调
                                    callback();
                                    return;
                                }

                                res.on('data', function (data) {
                                    chunks.push(data);
                                });

                                res.on('end', function () {
                                    var buf = Buffer.concat(chunks);
                                    var m = nexturl.match(/^http:\/\/.+\/(.+\/.+\/.+)\/(\d+\.jpg)/);
                                    var filename = m[1] + '/' + m[2];
                                    fs.writeFile(filename, buf, function () {
                                        console.log('保存图片到文件:' + filename);
                                        var m = nexturl.match(/(\d+)\.jpg$/);
                                        var nj;
                                        if (m[1][0] === '0') {
                                            if (m[1][1] < 9) {
                                                nj = '0' + (parseInt(m[1][1]) + 1);
                                            } else {
                                                nj = 10;
                                            }

                                        } else {
                                            nj = parseInt(m[1]) + 1 + '';
                                        }
                                        nj += '.jpg'
                                        //下一张图片的位置
                                        nexturl = nexturl.replace(/\d+\.jpg/, nj);
                                        callback();
                                    });
                                });

                            })
                        },
                        function (err) {
                            console.log('跳出循环:' + aurl);
                            callback();
                        }
                    );
                }],
            },
            function (err, result) {
                if (err) {
                    console.error(err);
                    parentcb(err, aurl);
                } else {
                    console.log('一个影集已经下载完成:' + aurl);
                    parentcb(null, aurl);
                }
            });

    },

    //下载所有的图片
    downloadImages: function (results, callback) {
        if ('getAllFirstImage' in results) {
            //根据第一张图片开始不断的下载
            var urls = results.getAllFirstImage;
            async.mapSeries(urls, this.downloadGallery.bind(this), function (err, results) {
                if (err) {
                    callback(err, null);
                } else {
                    //返回所有成功的结果回去
                    callback(null, results);
                }
            });
        } else {
            callback('获取不到第一张图片的数据', null);
        }
    },

    //读取页面的第一张图片,剩下的累加操作
    getFirstImage: function (aurl, callback) {
        request(aurl, function (err, res, body) {
            if (!err && res.statusCode == 200) {
                var $ = cheerio.load(body);
                var images = $('#contents img');
                var firstImg = images.first().attr('src');
                var flagIndex = firstImg.lastIndexOf('!');
                if (flagIndex != -1) {
                    firstImg = firstImg.slice(0, flagIndex);
                }
                callback(null, firstImg);
            } else {
                console.error(err);
                callback(err, null);
            }
        });
    },

    //读取所有的第一张图片
    getAllFirstImage: function (urls, callback) {
        async.mapLimit(urls, 4, this.getFirstImage.bind(this), function (err, results) {
            //console.log('已经获取到所有的第一张图片地址');
            console.log('所有的第一张图片地址:' + util.inspect(results, true));
            callback(null, results);
        });
    }
}

var pic = new Picture5442()
pic.main();

你可能感兴趣的:(nodejs)