經過前面五天的學習,對Node.js開發已經逐漸入門,今天結合之前學到的東西,開發一個小示例【爬取某圖片網站的圖片】來鞏固基礎知識,僅供學習分享使用,如有不足之處,還請指正。 ...
經過前面五天的學習,對Node.js開發已經逐漸入門,今天結合之前學到的東西,開發一個小示例【爬取某圖片網站的圖片】,僅供學習分享使用,如有不足之處,還請指正。
涉及知識點
開發一個小爬蟲,涉及的知識點如下所示:
- https模塊,主要是用戶獲取網路資源,如:網頁源碼,圖片資源等。
- cheerio模塊,主要用於解析html源碼,並可訪問,查找html節點內容。
- fs模塊,主要用於文件的讀寫操作,如保存圖片,日誌等。
- 閉包,主要是對於非同步操作,對象的隔離保護。
cheerio簡介
什麼是cheerio ?
cheerio是為伺服器特別定製的,快速、靈活、實施的jQuery核心實現。主要用於在服務端解析html。特點如下所示:
- 易用,語法類似jQuery語法,從jQuery庫中去除了所有 DOM不一致性和瀏覽器尷尬的部分。
- 解析快,比JSDOM快八倍。
- 靈活,Cheerio 封裝了相容的htmlparser。Cheerio 幾乎能夠解析任何的 HTML 和 XML document。
安裝cheerio
首先在命令行,切換到程式目錄,然後輸入安裝命令進行安裝,如下所示:
1 cnpm install cheerio
安裝過程,如下所示:
準備工作
在編寫爬蟲之前,首先需要分析目標內容,本次需要爬取的是某網站,星空類型的圖片內容,經過分析,發現所有的圖片都是在ul下每一個li中的a標簽內的img中,本次只需要解析出img的src屬性,即可獲取圖片的下載路徑。如下所示:
核心代碼
經過以上分析,通過Node.js編寫代碼,分為兩步,獲取所有圖片的url路徑,即解析所有目標img元素的src屬性。然後再下載具體圖片進行保存即可。
引用所需要的功能模塊,如下所示:
1 var https = require('https'); 2 var cheerio = require('cheerio'); 3 var fs = require('fs');
獲取並解析html頁面內容,如下所示:
1 //爬取的網址 2 var addrs=['https://www.*****.com/topic/show_27202_1.html','https://www.******.com/topic/show_27202_2.html','https://www.*****.com/topic/show_27202_3.html']; 3 var logger = fs.createWriteStream('./download/log.txt',{flags:'a+',autoClose:'true'}); 4 5 for(i in addrs){ 6 (function(num){ 7 var addr = addrs[num]; 8 //創建目錄 9 var p1 = new Promise(function(resolve,reject){ 10 fs.access('./download',function(err){ 11 if(err){ 12 fs.mkdir('./download',function(e){ 13 if(e){ 14 console.log('創建失敗'); 15 } 16 }); 17 }else{ 18 resolve("success"); 19 } 20 }); 21 }); 22 23 p1.then(function(datas){ 24 var html=''; 25 var p2 = new Promise(function(resolve,reject){ 26 https.get(addr,function(res){ 27 res.on('data',function(data){ 28 html+=data.toString(); 29 }) 30 res.on('end',function(){ 31 resolve("success"); 32 }); 33 34 }); 35 36 }); 37 p2.then(function(data){ 38 //下載完成後,進行解析 39 const $ =cheerio.load(html); 40 var lis = $('#img-list-outer').find('li'); 41 for(var j=0;j<lis.length-1;j++){ 42 var li = lis[j]; 43 var src =$(li).find('a').find('img').attr('src'); 44 //console.log(src); 45 //console.log('-------------------------'); 46 var imgurl='https:'+src; 47 download(imgurl); 48 var msg='['+j+']下載成功:'+imgurl; 49 logger.write(msg+'\n'); 50 console.log(msg); 51 } 52 }); 53 }); 54 })(i); 55 }
註意:因為所有爬取的目標共分為3頁,所以用到了迴圈,並且在迴圈中用到了閉包。
下載並保存單張圖片代碼,如下所示:
1 //下載圖片 2 function download(imgurl){ 3 var p1 = new Promise(function(resolve,reject){ 4 https.get(imgurl,function(res){ 5 var imgName=imgurl.substr(imgurl.lastIndexOf('/')+1); 6 var stream = fs.createWriteStream('./download/'+imgName); 7 res.pipe(stream); 8 setTimeout(function(){ 9 resolve('success'); 10 },300); 11 12 }); 13 }); 14 p1.then(function(data){ 15 return; 16 }); 17 }
示例截圖
開發完成後,運行代碼,如下所示:
爬取的圖片,保存在文件夾中,如下所示:
註意:添加日誌,是為了方便記錄程式執行過程,對比圖片和日誌,便於發現問題。
備註
學而時習之,不亦說乎?有朋自遠方來,不亦樂乎?人不知而不慍,不亦君子乎?
作者:小六公子
出處:http://www.cnblogs.com/hsiang/
本文版權歸作者和博客園共有,寫文不易,支持原創,歡迎轉載【點贊】,轉載請保留此段聲明,且在文章頁面明顯位置給出原文連接,謝謝。
關註個人公眾號,定時同步更新技術及職場文章