项目初始化
建立一个package.json文件,webstorm疾速建立package.json异常简朴。
运用 npm init 疾速建立。
东西模块
须要下载的的模块
- superagent 页面数据下载
- cheerio 页面数据剖析
这是2个npm包,我们先下载:
npm install superagent cheerio --save
须要引入的模块
- fs
- path
引入项目依靠
const cheerio = require('cheerio');
const agent = require('superagent');
const path = require('path');
const fs = require('fs');
定义地点数组
我们愿望以行列的情势逐一对这些地点举行接见,猎取HTML代码,以便后续处置惩罚:
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"
}];
定义数据构造
慕课网课程列表:
对此我们定义以下的数据构造:
[
{
page: 1,
data: [
{
title:"", // 课程题目
imgurl:"", // 课程图片
level:"", // 品级
studynum:0, // 进修人数
description:"xxxx" // 课程形貌
}
...... // 每一个页面有多条课程信息
]
}
...... // 一共有多个页面
]
superagent 页面数据下载
superagent是nodejs里一个异常轻易的客户端要求代码模块,superagent是一个轻量级的,渐进式的ajax API,可读性好,进修曲线低,内部依靠nodejs原生的要求API,适用于nodejs环境下。
基础运用要领:详细的请自行点击衔接检察哟...
request
.get('/login')
.end(function(err, res){
// code
});
cheerio 页面数据剖析
cheerio是一个node的库,能够理解为一个Node.js版本的jquery,用来从网页中以 css selector取数据,运用体式格局和jquery基础雷同。
须要先loading一个须要加载html文档,背面就能够jQuery一样运用操纵页面了。
基础运用要领:详细的请自行点击衔接检察哟...
const cheerio = require('cheerio');
const $ = cheerio.load('<ul id="fruits">...</ul>');
$('#fruits').addClass('newClass');
运用Promise完成行列
这才是本篇文章的重头戏…
- 我们须要运用数组的一个要领 reduce()
arr.reduce([callback, initialValue])
有不太懂这个要领的能够检察我写的笔记:https://segmentfault.com/n/13…
reduce() 要领吸收一个函数作为累加器(accumulator),数组中的每一个值(从左到右)最先缩减,终究为一个值。
callback (实行数组中每一个值的函数,包括四个参数)
initialValue (作为第一次挪用 callback 的第一个参数。)
- 另有一个是Promise完成异步处置惩罚
有不太懂这个要领的能够检察我写的笔记: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());
将数据写入result.json文件中
代码完成:
// 写入数据
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 文件,其构造也相符我们的预期:
至此,这篇文章也就完毕啦,假如您有好的主意请留言哟。
延续进修中…