async太好用了,用了兩個小時寫的程式碼
阿新 • • 發佈:2019-02-01
/* 從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();