用Promise完成行列(爬一爬慕课网HTML代码)

项目初始化

建立一个package.json文件,webstorm疾速建立package.json异常简朴。
运用 npm init 疾速建立。

东西模块

须要下载的的模块

这是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"
}];

定义数据构造

慕课网课程列表:
《用Promise完成行列(爬一爬慕课网HTML代码)》

对此我们定义以下的数据构造:

 [
     {
      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

能够看到终端有序次的输出了以下内容:

《用Promise完成行列(爬一爬慕课网HTML代码)》

当翻开天生的 result.json 文件,其构造也相符我们的预期:
《用Promise完成行列(爬一爬慕课网HTML代码)》

至此,这篇文章也就完毕啦,假如您有好的主意请留言哟。

延续进修中…

    原文作者:五月花开
    原文地址: https://segmentfault.com/a/1190000013910680
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞