用Promise实现队列(爬一爬慕课网HTML代码)
项目初始化
创建一个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 文件,其结构也符合我们的预期:
至此,这篇文章也就结束啦,如果您有好的想法请留言哟。
持续学习中...
用Promise实现队列(爬一爬慕课网HTML代码)相关推荐
- python爬虫图片实例-Python爬虫爬取煎蛋网图片代码实例
这篇文章主要介绍了Python爬虫爬取煎蛋网图片代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 今天,试着爬取了煎蛋网的图片. 用到的包: ...
- python爬图代码实例_Python爬虫爬取煎蛋网图片代码实例
这篇文章主要介绍了Python爬虫爬取煎蛋网图片代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 今天,试着爬取了煎蛋网的图片. 用到的包: ...
- Python爬虫爬取煎蛋网图片代码实例
这篇文章主要介绍了Python爬虫爬取煎蛋网图片代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 今天,试着爬取了煎蛋网的图片. 用到的包: ...
- python爬虫爬取慕课网中的图片
我们简单地爬取慕课网中免费课程下的第一页的图片,如想爬取多页图片,可以添加for循环自行实现 python版本:3.6.5 爬取网址:http://www.imooc.com/course/list ...
- 小白scrapy试炼-爬取慕课网免费课程
本文参考博客: scrapy爬虫-爬取慕课网全部课程 scrapy爬虫框架入门实例 准备工作: anaconda(为了简单安装scrapy) 安装scrapy的方法有好多种,原来在pip上花了挺多时间 ...
- Python爬虫学习笔记 (9) [初级] 小练习 爬取慕课网课程清单
更新日期: 2021.03.28 本节学习内容 : 练习使用 bs4 和 xlwings - 爬取慕课网免费课程清单并存为 Excel 文件. 目录 1. 目标信息 2. 爬取步骤 3. 代码 5. ...
- 100行代码教你爬取斗图网(Python多线程队列)
100行代码教你爬取斗图网(Python多线程队列) 前言 根据之前写的两篇文章,想必大家对多线程和队列有了一个初步的了解,今天这篇文章就来实战一下,用多线程 + 队列 爬取斗图网的全网图片. 你还在 ...
- python爬取小说基本信息_python实战项目:爬取某小说网
项目文档: 项目简介: 爬取某小说网首页中的全部小说,并储存到数据库中 项目版本 :python2.7.12 项目源码: 源码已上传 github: 源码github 项目总览: 1. 爬取小说首页中 ...
- 爬虫笔记——多线程爬取斗图网表情包(threading)
爬虫笔记--多线程爬取斗图网表情包(threading) 网站观察 爬取框架 具体代码 斗图网网址:斗图网,这里以爬取最新套图为例. 网站观察 在网页翻页操作中可以看到网页是非动态加载的(page为页 ...
最新文章
- 终于有人把中台说清楚了
- 02-线性结构3 Reversing Linked List
- Cisco PT模拟实验(12) 路由器静态路由的配置
- 厉害了!Python+matplotlib制作8个排序算法的动画
- Android调试相关的技术常识
- hibernate数据的三种存在状态(只与事务有关)
- 有用的Chrome扩展介绍 - Octotree - GitHub code tree
- Spring 4 官方文档学习(十)数据访问之JDBC
- vim复制、删除和粘贴一行
- 恋舞服务器维修,2144《梦幻恋舞》关闭充值及关服公告
- Java8————Stream API
- pandas筛选某个列值是否位于某个列表内
- 苹果id无法登陆_《英雄联盟手游》苹果id和拳头账户合并教程 苹果id如何绑定拳头账号...
- 计算机软件设计费计算标准,水利工程咨询、勘测设计费收费标准及计算程序
- 小白学习MySQL - 一次慢SQL的定位
- 【bzoj1818】[Cqoi2010]内部白点
- layui 日期选择器 laydate详细参数用法大全,一键复制粘贴
- Hinton 深度学习论文总结
- 问题1084:搭数字Ⅰ
- 传感器实验——寻迹模块
热门文章
- [转载]生活在 Emacs 中
- 软工实践第八次作业(软件工程实践总结)
- Leetcode: 2. Add Two Numbers
- android scrollview listview显示不全
- cocos2d-x中使用可加密Sqlite存储玩家数据
- 《精通.Net核心技术》
- C++11---之auto
- LeetCode-20.有效的括号(栈的使用+map的count)
- java海滩上有一_海滩上有一堆桃子,五只猴子来分-海滩上有一堆桃子,五只猴子来分java实现-吾爱编程网...
- java jar包存放位置_获得运行jar包存放路径的方法