建立一個package.json文件,webstorm快捷建立package.json很是簡單。
使用 npm init 快速建立。css
須要下載的的模塊 html
這是2個npm包,咱們先下載:node
npm install superagent cheerio --save
須要引入的模塊 jquery
const cheerio = require('cheerio'); const agent = require('superagent'); const path = require('path'); const fs = require('fs');
咱們但願以隊列的形式逐個對這些地址進行訪問,獲取HTML代碼,以便後續處理:git
const urls = [{ page:1, url:"https://www.imooc.com/course/list?c=fe&page=1" },{ page:2, url:"https://www.imooc.com/course/list?c=fe&page=2" },{ page:3, url:"https://www.imooc.com/course/list?c=fe&page=3" }];
慕課網課程列表:
github
對此咱們定義以下的數據結構:web
[ { page: 1, data: [ { title:"", // 課程標題 imgurl:"", // 課程圖片 level:"", // 等級 studynum:0, // 學習人數 description:"xxxx" // 課程描述 } ...... // 每個頁面有多條課程信息 ] } ...... // 一共有多個頁面 ]
superagent是nodejs裏一個很是方便的客戶端請求代碼模塊,superagent是一個輕量級的,漸進式的ajax API,可讀性好,學習曲線低,內部依賴nodejs原生的請求API,適用於nodejs環境下。
基本使用方法:具體的請自行點擊鏈接查看喲...
ajax
request .get('/login') .end(function(err, res){ // code });
cheerio是一個node的庫,能夠理解爲一個Node.js版本的jquery,用來從網頁中以 css selector取數據,使用方式和jquery基本相同。
須要先loading一個須要加載html文檔,後面就能夠jQuery同樣使用操做頁面了。npm
基本使用方法:具體的請自行點擊鏈接查看喲...
json
const cheerio = require('cheerio'); const $ = cheerio.load('<ul id="fruits">...</ul>'); $('#fruits').addClass('newClass');
這纔是本篇文章的重頭戲...
arr.reduce([callback, initialValue])
有不太懂這個方法的能夠查看我寫的筆記:https://segmentfault.com/n/13...
reduce() 方法接收一個函數做爲累加器(accumulator),數組中的每一個值(從左到右)開始縮減,最終爲一個值。
callback (執行數組中每一個值的函數,包含四個參數)
initialValue (做爲第一次調用 callback 的第一個參數。)
有不太懂這個方法的能夠查看我寫的筆記:https://segmentfault.com/n/13...
具體是使用Promise的這個方法:
Promise.resolve()
這個方法返回一個fulfilled的Promise實例,或者原始的Promise實例。
代碼實現:
// 實現隊列 // 本質: 對.then()方法實現累加 let curPromise = urls.reduce((promise,curl) => { return promise.then(() => { return new Promise(resolve => { // 網絡獲取當前地址的網頁內容 requestGet(curl,() => { resolve(); }); }); }); },Promise.resolve());
代碼實現:
// 寫入數據 curPromise.then(()=>{ fs.writeFile('result.json', JSON.stringify(result), function (err) { if(err) throw new Error("appendFile failed..."); console.log("數據寫入success..."); }); });
// 項目依賴 const cheerio = require('cheerio'); const agent = require('superagent'); const path = require('path'); const fs = require('fs'); // 地址數據 const urls = [{ page:1, url:"https://www.imooc.com/course/list?c=fe&page=1" },{ page:2, url:"https://www.imooc.com/course/list?c=fe&page=2" },{ page:3, url:"https://www.imooc.com/course/list?c=fe&page=3" }]; // 最終的數據 let result = []; // 數據結構 /** * [ * { * page: 1, * data: [ * {title:xx,imgurl:xx...}, * ...... * ] * } * ...... * ] */ // 發起get請求 function requestGet(urlObj,callback){ agent.get(urlObj.url) .end((err,res) => { if(err) throw new Error(err); // 分析頁面 let pageJson = analysis(res.text); // 拼接數據 result.push({ page:urlObj.page, data:pageJson }); console.log(`寫入第${urlObj.page}頁的數據...`); // 執行回調 callback(); }); } // 對網頁分析 function analysis(data){ let page = []; let $ = cheerio.load(data); let courseArr = $(".course-list").find(".course-card-container"); courseArr.each((index,element) => { let _this = $(element); // 組裝數據 page.push({ title:_this.find(".course-card-name").text(), imgurl:path.join("http:",_this.find(".course-card-top img").attr("src")), level:_this.find(".course-card-info span:first-child").text(), // level:_this.find(".icon-set_sns").parent().prev().text(), studynum:_this.find(".icon-set_sns").parent().text(), description:_this.find(".course-card-desc").text() }); }); return page; } // 實現隊列 // 本質: 對.then()方法實現累加 let curPromise = urls.reduce((promise,curl) => { return promise.then(() => { return new Promise(resolve => { // 具體的內容 requestGet(curl,() => { resolve(); }); }); }); },Promise.resolve()); // 寫入數據 curPromise.then(()=>{ fs.writeFile('result.json', JSON.stringify(result), function (err) { if(err) throw new Error("appendFile failed..."); console.log("數據寫入success..."); }); });
node app.js
能夠看到終端有次序的輸出瞭如下內容:
當打開生成的 result.json 文件,其結構也符合咱們的預期:
至此,這篇文章也就結束啦,若是您有好的想法請留言喲。
持續學習中...