需要用到的第三方模塊有:
10多年的紅塔網(wǎng)站建設(shè)經(jīng)驗(yàn),針對設(shè)計(jì)、前端、開發(fā)、售后、文案、推廣等六對一服務(wù),響應(yīng)快,48小時(shí)及時(shí)工作處理。網(wǎng)絡(luò)營銷推廣的優(yōu)勢是能夠根據(jù)用戶設(shè)備顯示端的尺寸不同,自動(dòng)調(diào)整紅塔建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設(shè)計(jì),從而大程度地提升瀏覽體驗(yàn)。創(chuàng)新互聯(lián)從事“紅塔網(wǎng)站設(shè)計(jì)”,“紅塔網(wǎng)站推廣”以來,每個(gè)客戶項(xiàng)目都認(rèn)真落實(shí)執(zhí)行。
superagent
superagent-charset (手動(dòng)指定編碼,解決GBK中文亂碼)
cheerio
express
async (并發(fā)控制)
完整的代碼,可以在我的github中可以下載。主要的邏輯邏輯在 netbian.js 中。
以彼岸桌面(http://www.netbian.com/)欄目下的風(fēng)景壁紙(http://www.netbian.com/fengjing/index.htm)為例進(jìn)行講解。
1. 分析URL
不難發(fā)現(xiàn):
首頁: 欄目/index.htm
分頁: 欄目/index_具體頁碼.htm
知道這個(gè)規(guī)律,就可以批量下載壁紙了。
2. 分析壁紙縮略圖,找到對應(yīng)壁紙的大圖
使用chrome的開發(fā)者工具,可以發(fā)現(xiàn),縮略圖列表在 class="list"的div里,a標(biāo)簽的href屬性的值就是單張壁紙所在的頁面。
部分代碼:
request .get(url) .end(function(err, sres){ var $ = cheerio.load(sres.text); var pic_url = []; // 中等圖片鏈接數(shù)組 $('.list ul', 0).find('li').each(function(index, ele){ var ele = $(ele); var href = ele.find('a').eq(0).attr('href'); // 中等圖片鏈接 if(href != undefined){ pic_url.push(url_model.resolve(domain, href)); } }); });
3. 以“http://www.netbian.com/desk/17662.htm”繼續(xù)分析
打開這個(gè)頁面,發(fā)現(xiàn)此頁面顯示的壁紙,依舊不是最高的分辨率。
點(diǎn)擊“下載壁紙”按鈕里的鏈接,打開新的頁面。
4. 以“http://www.netbian.com/desk/17662-1920x1080.htm”繼續(xù)分析
打開這個(gè)頁面,我們最終要下載的壁紙,放在一個(gè)table里面。如下圖,http://img.netbian.com/file/2017/0203/bb109369a1f2eb2e30e04a435f2be466.jpg
才是我們最終要下載的圖片的URL(幕后BOSS終于現(xiàn)身了(@ ̄ー ̄@))。
下載圖片的代碼:
request .get(wallpaper_down_url) .end(function(err, img_res){ if(img_res.status == 200){ // 保存圖片內(nèi)容 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
選擇欄目和頁面,點(diǎn)擊“開始”按鈕:
并發(fā)請求服務(wù)器,下載圖片。
完成~
圖片的存放目錄按照 欄目+頁碼 的形式保存。
附上完整的圖片下載的代碼:
/** * 下載圖片 * @param {[type]} url [圖片URL] * @param {[type]} dir [存儲(chǔ)目錄] * @param {[type]} res [description] * @return {[type]} [description] */ var down_pic = function(url, dir, res){ var domain = 'http://www.netbian.com'; // 域名 request .get(url) .end(function(err, sres){ var $ = cheerio.load(sres.text); var pic_url = []; // 中等圖片鏈接數(shù)組 $('.list ul', 0).find('li').each(function(index, ele){ var ele = $(ele); var href = ele.find('a').eq(0).attr('href'); // 中等圖片鏈接 if(href != undefined){ pic_url.push(url_model.resolve(domain, href)); } }); var count = 0; // 并發(fā)計(jì)數(shù)器 var wallpaper = []; // 壁紙數(shù)組 var fetchPic = function(_pic_url, callback){ count++; // 并發(fā)加1 var delay = parseInt((Math.random() * 10000000) % 2000); console.log('現(xiàn)在的并發(fā)數(shù)是:' + count + ', 正在抓取的圖片的URL是:' + _pic_url + ' 時(shí)間是:' + delay + '毫秒'); setTimeout(function(){ // 獲取大圖鏈接 request .get(_pic_url) .end(function(err, ares){ var $$ = cheerio.load(ares.text); var pic_down = url_model.resolve(domain, $$('.pic-down').find('a').attr('href')); // 大圖鏈接 count--; // 并發(fā)減1 // 請求大圖鏈接 request .get(pic_down) .charset('gbk') // 設(shè)置編碼, 網(wǎng)頁以GBK的方式獲取 .end(function(err, pic_res){ var $$$ = cheerio.load(pic_res.text); var wallpaper_down_url = $$$('#endimg').find('img').attr('src'); // URL var wallpaper_down_title = $$$('#endimg').find('img').attr('alt'); // title // 下載大圖 request .get(wallpaper_down_url) .end(function(err, img_res){ if(img_res.status == 200){ // 保存圖片內(nèi)容 fs.writeFile(dir + '/' + wallpaper_down_title + path.extname(path.basename(wallpaper_down_url)), img_res.body, 'binary', function(err){ if(err) console.log(err); }); } }); wallpaper.push(wallpaper_down_title + '下載完畢
'); }); callback(null, wallpaper); // 返回?cái)?shù)據(jù) }); }, delay); }; // 并發(fā)為2,下載壁紙 async.mapLimit(pic_url, 2, function(_pic_url, callback){ fetchPic(_pic_url, callback); }, function (err, result){ console.log('success'); res.send(result[0]); // 取下標(biāo)為0的元素 }); }); };
特別需要注意的兩點(diǎn):
1. “彼岸桌面”網(wǎng)頁的編碼是“GBK”的。而nodejs本身只支持“UTF-8”編碼。這里我們引入“superagent-charset”模塊,用于處理“GBK”的編碼。
附上github里的一個(gè)例子
https://github.com/magicdawn/superagent-charset
2. nodejs是異步的,同一時(shí)間發(fā)送大量的請求,有可能被服務(wù)器認(rèn)為是惡意請求而拒絕。 因此這里引入“async”模塊,用于并發(fā)的處理,使用的方法是:mapLimit。
mapLimit(arr, limit, iterator, callback)
這個(gè)方法有4個(gè)參數(shù):
第1個(gè)參數(shù)是數(shù)組。
第2個(gè)參數(shù)是并發(fā)請求的數(shù)量。
第3個(gè)參數(shù)是迭代器,通常是一個(gè)函數(shù)。
第4個(gè)參數(shù)是并發(fā)執(zhí)行后的回調(diào)。
這個(gè)方法的作用是將arr中的每個(gè)元素同時(shí)并發(fā)limit次拿給iterator去執(zhí)行,執(zhí)行結(jié)果傳給最后的callback。
后話
至此,便完成了圖片的下載。
完整的代碼,已經(jīng)放在github上
以上就是本文的全部內(nèi)容,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作能帶來一定的幫助,同時(shí)也希望多多支持創(chuàng)新互聯(lián)!