Node實戰-----爬取網頁圖片


      在本篇博文中我將實現一個完整的實例:主要使用Node.js爬取一個網頁,需要通過第三方模塊cheerio.js分析這個網頁的內容,最后將這個網頁的圖片保存個在本地。

一、項目目錄與思路

      新建一個項目名為:project_01,輸入命令在控制台,使其生成package.json文件:

命令:

npm init

 

在控制台輸入npm install命令下載需要的模塊,在本項目中需要的request和cheerio模塊,將使用命令進行下載到本地:

命令:

npm install request cheerio -S

 

 

此時項目的文件夾的目錄為:

 

  •  img文件夾用來存儲圖片文件
  • node_modules文件夾是模塊默認的保存位置
  • index.js文件是整個項目的入口文件。
  • config.js文件是配置文件,用來存放網頁地址和圖片文件夾的路徑,這樣做的目的是使整個項目的可拓展性增強。
  • analyze.js文件用來存儲分析DOM的方法。
  • package.json文件是包的描述文件。

打開node_modules文件夾可以看到相應的模塊:

 

 

 

       整體的思路:通過第三方模塊request的請求網頁地址,從而得到整個網頁的DOM結構,根據DOM結構利用cheerio模塊分析出圖片文件的地址,再次請求這個地址,再次請求這個地址,最后將得到的圖片數據存儲在本地。

   二、   配置網頁地址及圖片存放的文件夾

配置內容:config.js中,在文件中通過exports導出這些配置內容,從而使其它文件可以使用

以爬碼農網為例

代碼:

config.js

 

const url='http://www.codeceo.com/';//填寫自己請求的具體的網址

const path=require('path');
const imgDir=path.join(__dirname,'img');

module.exports.url=url;
module.exports.imgDir=imgDir;

 

三、解析DOM得到的圖片地址

        得到DOM結構之后,將分析DOM部分代碼寫入analyze.js文件中,通過cheerio得到每一張圖片的地址,最后利用一個回調函數callback處理這個地址(這里的回調函數callback是發送請求):

代碼:

analyze.js:

const cheerio=require('cheerio');
const fs=require('fs');
function findImg(dom,Callback){
    
    let $=cheerio.load(dom);
    $('img').each(function(i,elem){
        
        let imgSrc=$(this).attr('src');
           Callback(imgSrc,i);
    });
    
}
module.exports.findImg=findImg;

  cheerio模塊可以像jQuery一樣操作DOM,這里得到的是請求網頁中每一張圖片的文件地址

       

 

四、請求圖片的地址以及圖片文件的保存

請求圖片的的地址:

     將請求的操作放在主模塊index.js文件中,將config.js和analyze.js文件引入這個模塊,利用request模塊請求圖片的地址,得到DOM結構,將DOM結構給analyze的findImg方法處理,代碼:

 

const http=require('http');
const fs=require('fs');
const request=require('request');
const path=require('path');
const config=require('./config');
const analyze=require('./analyze');


function start(){
    
    request(config.url,function(err,res,body){
        
        console.log('start');
        if(!err && res){
            
            console.log('start');
            analyze.findImg(body);
        }
    })
}

 

圖片文件的保存:

   通過分析DOM結構得到圖片地址后,利用request再次發送請求,將請求得到的數據寫入本地即可,這里也將其封裝為一個函數,追加在index.js文件中:

代碼:

function downLoad(imgUrl,i){
    let ext=imgUrl.split('.').pop();
    
    request(imgUrl).pipe(fs.createWriteStream(path.join(config.imgDir,i+'.'+ext),{
        
        'enconding':'binary'
    }))
    
    console.log(i);
}

注意:所獲取的數據的二進制數據,所以一定要設置編碼格式為binary,因為writeFile的默認編碼格式為utf-8,否則保存的圖片無法打開。

      同時,我們需要將這個download函數作為參數傳遞給analyze模塊的findImg方法,最后運行這個項目的主函數start(),這樣項目才會運行起來

index.js

const http=require('http');
const fs=require('fs');
const request=require('request');
const path=require('path');
const config=require('./config');
const analyze=require('./analyze');


function start(){
    
    request(config.url,function(err,res,body){
        
        console.log('start');
        if(!err && res){
            
            console.log('start');
            analyze.findImg(body,downLoad);
        }
    })
}

function downLoad(imgUrl,i){
    let ext=imgUrl.split('.').pop();
    
    request(imgUrl).pipe(fs.createWriteStream(path.join(config.imgDir,i+'.'+ext),{
        
        'enconding':'binary'
    }))
    
    console.log(i);
}
start();

 

 

最終的結果顯示:

 

 運行代碼不到5秒鍾,就抓取完了並命名好了,這相對於我們手動保存,速度非常快

 你想抓取哪個網站的圖片就抓取哪個網站的圖片(當然除了那些做了防爬蟲處理的)。

項目源代碼:https://github.com/life2022/SSH_Forum/tree/master/project_01

  

 

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM