使用nodejs下載風景壁紙

來源:互聯網
上載者:User

標籤:開始   規律   char   例子   分享   function   批量下載   index   使用   

 

上一篇部落格講解了使用nodejs爬取部落格園的博文,這次帶給大家的是下載網路上的圖片。

 

需要用到的第三方模組有:

superagent

superagent-charset  (手動改指定編碼,解決GBK中文亂碼)

cheerio

express

async (並發控制)

 

完整的代碼,可以在我的github中可以下載。主要的邏輯邏輯在 netbian.js 中。

 

 

以彼岸案頭(http://www.netbian.com/)欄目下的風景壁紙(http://www.netbian.com/fengjing/index.htm)為例進行講解。

1. 分析URL 

不難發現:

首頁: 欄目/index.htm

分頁: 欄目/index_具體頁碼.htm

知道這個規律,就可以批量下載壁紙了。

 

2. 分析壁紙縮圖,找到對應壁紙的大圖

使用chrome的開發人員工具,可以發現,縮圖列表在 class="list"的div裡,a標籤的href屬性的值就是單張壁紙所在的頁面。

 

部分代碼:

 1 request 2     .get(url) 3     .end(function(err, sres){ 4  5         var $ = cheerio.load(sres.text); 6         var pic_url = []; // 中等圖片連結數組 7         $(‘.list ul‘, 0).find(‘li‘).each(function(index, ele){ 8             var ele = $(ele); 9             var href = ele.find(‘a‘).eq(0).attr(‘href‘); // 中等圖片連結10             if(href != undefined){11                 pic_url.push(url_model.resolve(domain, href));12             }13         });14 });

 

3. 以“http://www.netbian.com/desk/17662.htm”繼續分析

開啟這個頁面,發現此頁面顯示的壁紙,依舊不是最高的解析度。

點擊“下載壁紙”按鈕裡的連結,開啟新的頁面。

 

4. 以“http://www.netbian.com/desk/17662-1920x1080.htm”繼續分析

開啟這個頁面,我們最終要下載的壁紙,放在一個table裡面。如,http://img.netbian.com/file/2017/0203/bb109369a1f2eb2e30e04a435f2be466.jpg 

才是我們最終要下載的圖片的URL(幕後BOSS終於現身了(@ ̄ー ̄@))。

 

下載圖片的代碼:

request.get(wallpaper_down_url).end(function(err, img_res){    if(img_res.status == 200){        // 儲存圖片內容        fs.writeFile(dir + ‘/‘ + wallpaper_down_title + path.extname(path.basename(wallpaper_down_url)), img_res.body, ‘binary‘, function(err){            if(err) console.log(err);        });    }});

 

開啟瀏覽器,訪問  http://localhost:1314/fengjing 

選擇欄目和頁面,點擊[開始] 按鈕:

 

並發請求伺服器,下載圖片。

 

完成~

 

圖片的存放目錄按照 欄目+頁碼 的形式儲存。

 

附上完整的圖片下載的代碼:

 1 /** 2  * 下載圖片 3  * @param  {[type]} url [圖片URL] 4  * @param  {[type]} dir [儲存目錄] 5  * @param  {[type]} res [description] 6  * @return {[type]}     [description] 7  */ 8 var down_pic = function(url, dir, res){ 9 10     var domain = ‘http://www.netbian.com‘; // 網域名稱11 12     request13     .get(url)14     .end(function(err, sres){15 16         var $ = cheerio.load(sres.text);17         var pic_url = []; // 中等圖片連結數組18         $(‘.list ul‘, 0).find(‘li‘).each(function(index, ele){19             var ele = $(ele);20             var href = ele.find(‘a‘).eq(0).attr(‘href‘); // 中等圖片連結21             if(href != undefined){22                 pic_url.push(url_model.resolve(domain, href));23             }24         });25 26         var count = 0; // 並發計數器27         var wallpaper = []; // 壁紙數組28         var fetchPic = function(_pic_url, callback){29 30             count++; // 並發加131 32             var delay = parseInt((Math.random() * 10000000) % 2000);33             console.log(‘現在的並發數是:‘ + count + ‘, 正在抓取的圖片的URL是:‘ + _pic_url + ‘ 時間是:‘ + delay + ‘毫秒‘);34             setTimeout(function(){35                 // 擷取大圖連結36                 request37                 .get(_pic_url)38                 .end(function(err, ares){39                     var $$ = cheerio.load(ares.text);40                     var pic_down = url_model.resolve(domain, $$(‘.pic-down‘).find(‘a‘).attr(‘href‘)); // 大圖連結41 42                     count--; // 並發減143 44                     // 請求大圖連結45                     request46                     .get(pic_down)47                     .charset(‘gbk‘) // 設定編碼, 網頁以GBK的方式擷取48                     .end(function(err, pic_res){49 50                         var $$$ = cheerio.load(pic_res.text);51                         var wallpaper_down_url = $$$(‘#endimg‘).find(‘img‘).attr(‘src‘); // URL52                         var wallpaper_down_title = $$$(‘#endimg‘).find(‘img‘).attr(‘alt‘); // title53 54                         // 下載大圖55                         request56                         .get(wallpaper_down_url)57                         .end(function(err, img_res){58                             if(img_res.status == 200){59                                 // 儲存圖片內容60                                 fs.writeFile(dir + ‘/‘ + wallpaper_down_title + path.extname(path.basename(wallpaper_down_url)), img_res.body, ‘binary‘, function(err){61                                     if(err) console.log(err);62                                 });63                             }64                         });65 66                         wallpaper.push(wallpaper_down_title + ‘下載完畢<br />‘);67                     });68                     callback(null, wallpaper); // 返回資料69                 });70             }, delay);71         };72 73         // 並發為2,下載壁紙74         async.mapLimit(pic_url, 2, function(_pic_url, callback){75             fetchPic(_pic_url, callback);76         }, function (err, result){77             console.log(‘success‘);78             res.send(result[0]); // 取下標為0的元素79         });80     });81 };

 

特別需要注意的兩點:

1. “彼岸案頭”網頁的編碼是“GBK”的。而nodejs本身只支援“UTF-8”編碼。這裡我們引入“superagent-charset”模組,用於處理“GBK”的編碼。

 

附上github裡的一個例子

https://github.com/magicdawn/superagent-charset

 

2.  nodejs是非同步,同一時間發送大量的請求,有可能被伺服器認為是惡意請求而拒絕。 因此這裡引入“async”模組,用於並發的處理,使用的方法是:mapLimit。

mapLimit(arr, limit, iterator, callback) 

這個方法有4個參數:

第1個參數是數組。

第2個參數是並發請求的數量。

第3個參數是迭代器,通常是一個函數。

第4個參數是並發執行後的回調。

這個方法的作用是將arr中的每個元素同時並發limit次拿給iterator去執行,執行結果傳給最後的callback。

 

後話

至此,便完成了圖片的下載。

完整的代碼,已經放在github上,歡迎star (☆▽☆)。

文筆有限,才學疏淺,若有不正確的地方,歡迎廣大博友指正。

 

使用nodejs下載風景壁紙

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.