1. 程式人生 > 其它 >Node.js基礎入門第六天

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 }

示例截圖

開發完成後,執行程式碼,如下所示:

 

 爬取的圖片,儲存在資料夾中,如下所示:

 

注意:新增日誌,是為了方便記錄程式執行過程,對比圖片和日誌,便於發現問題。

備註

學而時習之,不亦說乎?有朋自遠方來,不亦樂乎?人不知而不慍,不亦君子乎?