在本篇博文中我將實現一個完整的實例:主要使用Node.js爬取一個網頁,須要經過第三方模塊cheerio.js分析這個網頁的內容,最後將這個網頁的圖片保存個在本地。node
新建一個項目名爲:project_01,輸入命令在控制檯,使其生成package.json文件:git
命令:github
npm init
在控制檯輸入npm install命令下載須要的模塊,在本項目中須要的request和cheerio模塊,將使用命令進行下載到本地:npm
命令:json
npm install request cheerio -S
此時項目的文件夾的目錄爲:dom
打開node_modules文件夾能夠看到相應的模塊:函數
總體的思路:經過第三方模塊request的請求網頁地址,從而獲得整個網頁的DOM結構,根據DOM結構利用cheerio模塊分析出圖片文件的地址,再次請求這個地址,再次請求這個地址,最後將獲得的圖片數據存儲在本地。網站
配置內容:config.js中,在文件中經過exports導出這些配置內容,從而使其它文件可使用ui
以爬碼農網爲例this
代碼:
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部分代碼寫入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