1. 程式人生 > 程式設計 >node.js做一個簡單的爬蟲案例教程

node.js做一個簡單的爬蟲案例教程

準備工作

  1. 首先,你需要下載 node,這個應該沒啥問題吧
  2. 原文要求下載 webstrom,我電腦上本來就有,但其實不用下載,完全在命令列裡面操作就行

建立工程

準備工作做完了,下面就開始建立工程了

  1. 首先,在你想要放資源的地方建立資料夾,比如我在 E 盤裡面建立了一個 myStudyNodejs 的資料夾
  2. 在命令列裡面進入你建立的資料夾 如圖
    進入 e 盤:E:
    進入資料夾:cd myStudyNodejs(你建立的資料夾的名字)
    注意全是英文符號
  3. 初始化專案,在你建立的資料夾下面執行 npm init 初始化專案
    一路回車,最後輸個 yes 就行
  4. 執行完以後,會在資料夾裡面生成一個 package.json 的檔案,裡面包含了專案的一些基本資訊。
  5. 安裝所需要的包
    在所建立的資料夾的目錄下執行
    npm install cheerio –save
    npm install request -save
    爬武大的話,這兩個包就夠了,如果想爬草榴需要額外的轉換編碼的包,windows 上面是
    npm install iconv-lite -save
    Mac 上面是 npm install iconv -save
    執行結果應該第二幅圖這樣,中間手滑少寫了個字母
  6. 建立檔案
    在你所建立的資料夾下面建立一個 data 資料夾用於儲存爬到的文字資料。
    建立一個 image 資料夾用於儲存圖片資料。
    建立一個 js 檔案用來寫程式。比如 study.js。(建立一個記事本檔案將 .txt 改為 .js)
    說明 –save 的目的是將專案對該包的依賴寫入到 package.json 檔案中。

圖1

圖2

武大計算機學院新聞爬蟲程式碼

下面就是武大計算機學院新聞的爬蟲程式碼了,複製到建立的 .js 檔案中,儲存。

var http = require('http');
var fs = require('fs');
var cheerio = require('cheerio');
var request = require('request');
var i = 0;
//初始url 
var url = "http://ciDZDDzdiVy
s.whu.edu.cn/a/xinwendongtaifabu/2018/0428/7053.html"; function fetchPage(x) { //封裝了一層函式 startRequest(x); } function startRequest(x) { //採用http模組向伺服器發起一次get請求 http.get(x,function (res) { var html = ''; //用來儲存請求的整個html內容 var titles = www.cppcns.com[]; res.setEncoding('utf-8'); //防止中文亂碼 //監聽data事件,每次取一塊資料 res.on('data',function (chunk) { html += chunk; }); //監聽end事件,如果整個網頁內容的html都獲取完畢,就執行回撥函式 res.on('end',function () { var $ = cheerio.load(html); //採用cheerio模組解析html var news_item = { //獲取文章的標題 title: $('div#container dt').text().trim(),i: i = i + 1,}; console.log(news_item); //列印新聞資訊 var news_title = $('div#container dt').text().trim(); savedContent($,news_title); //儲存每篇文章的內容及文章標題 savedImg($,news_title); //儲存每篇文章的圖片及圖片標題 //下一篇文章的url var nextLink="http://cs.whu.edu.cn" + $("dd.Paging a").attr('href'); str1 = nextLink.split('-'); //去除掉url後面的中文 str = encodeURI(str1[0]); //這是亮點之一,通過控制I,可以控制爬取多少篇文章.武大隻有8篇,所以設定為8 if (i <= 8) { fetchPage(str); } }); }).on('error',function (err) { console.log(err); }); } //該函式的作用:在本地儲存所爬取的新聞內容資源 function savedContent($,news_title) { $('dd.info').each(function (index,item) { var x = $(this).text(); var y = x.substring(0,2).trim(); if (y == '') { x = x + '\n'; //將新聞文字內容一段一段新增到/data資料夾下,並用新聞的標題來命名檔案 fs.appendFile('./data/' + news_title + '.txt',x,'utf-8',function (err) { if (err) { console.log(err); } }); } }) } //該函式的作用:在本地儲存所爬取到的圖片資源 function savedImg($,news_title) { $('dd.info img').each(function (index,item) { var img_title = $(this).parent().next().text().trim(); //獲取圖片的標題 if(img_title.length>35||img_title==""){ img_title="Null"; } var img_filename = img_title + '.jpg'; var img_src = 'http://cs.whu.edu.cn' + $(this).attr('src'); //獲取圖片的url //採用request模組,向伺服器發起一次請求,獲取圖片資源 request.head(img_src,function(err,res,body){ if(err){ console.log(err); } }); request(img_src).pipe(fs.createWriteStream('./image/'+news_title + '---' + img_filename)); //通過流的方式,把圖片寫到本地/image目錄下,並用新聞的標題和圖片的標題作為圖片的名稱。 }) } fetchPage(url); //主程式開始執行

下面就是激動人心的時刻了,在當前資料夾下面,執行建立的 js 檔案,比如我的是 news.js。

npm news.js

圖3

文字資源:

圖4

圖片資源:

圖5

草榴技術討論區爬蟲

爬完武大的新聞並不過癮,於是嘗試了一波爬草榴的技術討論區(當然也能爬一些你懂的)。其中遇到了一些問題。
爬草榴的時候,傳送 http 請求報文頭裡面需要包含 User-Agent 欄位,於是需要把 初始url 做如下改變

var url = {
	hostname: 'cl.5fy.xyz',path: '/thread0806.?fid=7',headers: {
		'Content-Type': 'text/html',//沒有這個欄位的話訪問不了
  	'User-Agent': 'Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML,like Gecko) Chrome/46.0.2490.86 Safari/537.36',}};

其次,nodejs 只支援 抓取 utf-8 字元編碼的,所以需要安裝額外的包來轉換編碼,所以修改程式碼如下

/*
* @Author: user
* @Date:   2018-04-28 19:34:50
* @Last Modified by:   user
* @Last Modified time: 2018-04-30 21:35:26
*/
var http = require('http');
var fs = require('fs');
var cheerio = require('cheerio');
var request = require('request');
var iconv=require('iconv-lite');
var i = 0;
  //用來判斷儲存還是訪問
  var temp=0;
  let startPage=3;//從哪一頁開始爬
  let page=startPage;
  let endPage=5;//爬到哪一頁
  let searchText='';//爬取的關鍵字,預設全部爬取,根據自己需要
  //初始url 
  var url = {
  hostname: '1024liuyouba.tk',path: '/thread0806.php?fid=16'+'&search=&page='+startPage,headers: {
    'Content-Type': 'text/html',//沒有這個欄位的話訪問不了
    'User-Agent': 'Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML,}};
//儲存首頁url
urlList=[];
//封裝了一層函式
function fetchPage(x) { 
  setTimeout(function(){  
    startRequest(x); },5000)
}
//首先儲存要訪問介面的url
function getUrl(x){
  temp++;
  http.get(x,function(res){
    var html = ''; 
    res.setEncoding('binary');
    res.on('data',function (chunk) {   
      html += chunk;
    });
    res.on('end',function () {
      var buf=new Buffer(html,'binary');
      var str=iconv.decode(buf,'GBK');
          var $ = cheerio.load(str); //採用cheerio模組解析html                
          $('tr.tr3 td.tal http://www.cppcns.comh3 a').each(function(){
            var search=$(this).text();
            if(search.indexOf(searchText)>=0){
            var nextLink="http://cl.5fy.xyz/" + $(this).attr('href');
            str1 = nextLink.split('-');  //去除掉url後面的中文
            str = encodeURI(str1[0]); 
            urlList.push(str); }
          })
          page++;
          if(page<endPage){
            //儲存下一頁url
            x.path='/thread0806.php?fid=16'+'&search=&page='+page,getUrl(x);
          }else if(urlList.length!=0){
            fetchPage(urlList.shift());
          }else{
            console.log('未查詢到關鍵字!');
          }
        })
  }).on('error',function (err) {
    console.log(err);
  });

}
function startRequest(x) {
  if(temp===0){
    getUrl(x);     
  }   
  else{
     //採用http模組向伺服器發起一次get請求      
     http.get(x,function (res) {     
        var html = '';        //用來儲存請求網頁的整個html內容
        res.setEncoding('binary');
        var titles = [];        
	     //監聽data事件,每次取一塊資料
	    res.on('data',function (chunk) {   
	      html += chunk;
	    });
	     //監聽end事件,如果整個網頁內容的html都獲取完畢,就執行回撥函式
	    res.on('end',function () {
	    	var buf=new Buffer(html,'binary');
	    	var str=iconv.decode(buf,'GBK');
	        var $ = cheerio.load(str); //採用cheerio模組解析html
	        var news_item = {
	          	//獲取文章的標題
	        	title: $('h4').text().trim(),//i是用來判斷獲取了多少篇文章
	        	i: i = i + 1,};
	    console.log(news_item);     //列印資訊
	  	var news_title = $('h4').text().trim();
		
	  	savedContent($,news_title);  //儲存每篇文章的內容及文章標題
		
	  	savedImg($,news_title);    //儲存每篇文章的圖片及圖片標題
		
	  	//如果沒訪問完繼續訪問
	  	if (urlList.length!=0 ) {
	    	fetchPage(urlList.shift());
	  	}
	});
}).on('error',function (err) {
    console.log(err);
  });
 }
}
       //該函式的作用:在本地儲存所爬取的文字內容資源
function savedContent($,news_title) {
	$("div.t2[style] .tpc_content.do_not_catch").each(function (index,item) {
          var x = $(this).text();       
          x = x + '\n';   
		  //將新聞文字內容一段一段新增到/data資料夾下,並用新聞的標題來命名檔案
		  fs.appendFile('./data/' + news_title + '.txt',function (err) {
			  if (err) {
			    console.log(err);
			  }
		  });
		})
 }
//該函式的作用:在本地儲存所爬取到的圖片資源
function savedImg($,news_title) {
  //建立資料夾
    fs.mkdir('./image/'+news_title,function (err) {
        if(err){console.log(err)}
      });
  $('.tpc_content.do_not_catch input[src]').each(function (index,item) {
        var img_title = index;//給每張圖片附加一個編號
        var img_filename = img_title + '.jpg';
        var img_src = $(this).attr('src'); //獲取圖片的url
//採用request模組,向伺服器發起一次請求,獲取圖片資源
request.head(img_src,body){
  if(err){
    console.log(err);
  }
});
setTimeout(function(){
  request({uri: img_src,ewww.cppcns.comncoding: 'binary'},function (error,response,body) {
    if (!error && response.statusCode == 200) {
      fs.writeFile('./image/'+news_title+'/' + img_filename,body,'binary',function (err) {
        if(err){console.log(err)}
      });
    }
  })
});
})
}
fetchPage(url);      //主程式開始執行

成果展示:

這裡寫圖片描述

到此這篇關於node.js做一個簡單的爬蟲案例教程的文章就介紹到這了,更多相關node.js做一個簡單的爬蟲內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!