您的位置:首页 > Web前端 > Node.js

慕课课程《进击Node.js基础(二)》的小爬虫

2017-09-06 17:52 537 查看

慕课课程《进击Node.js基础(二)》的小爬虫

在imooc的教学视频中学习Node.js,发现在课程中用
Promise
来写了一个并发提交扒取数据的小爬虫,跟着课程亦步亦趋地学习,在敲代码时发现有两个tips:

慕课重新搭建了网页结构,标签及其类名发生变动

观看人数由最初写在页面内部能够通过cheerio直接扒取,变成通过ajax异步提交调取再渲染,直接DOM操作无效

针对第一点,倒还好办,只需要根据当前的结构,然后用着和
jQuery
语法基本一样的
cheerio
即可重新获取,最多就是标题的
div
中多了一些其他信息,用
正则
配合
replace()
即可满足数据的获取。

let chapterTitle = chapter.find('strong').text().replace(chapter.find('.chapter-content').text().trim(), '').trim().replace(/\s+/g, ' ')


针对第二点,就需要同步发送
ajax
请求,对返回的数据进行处理,重新传参给函数,从而对
number
进行正确赋值,也才能满足后续的
排序输出
的功能。

主要思路,就是把
请求接口的url
作为第二个参数,传入
Promise实例


videoIds.forEach((videoId) => {
fetchCourseArray.push(getPageAsync(baseUrl + videoId, requestNum + videoId))// url1 和 url2
})


然后在
Promise实例
中,对第二个参数在第一个请求的
response.on('end', () => {})
中进行操作:

http.get(url2, (response2) => {
response2.on('data', (chunk) => {
info.numInfo = JSON.parse(chunk.toString()).data[0].numbers // 获取到的数据是buffer格式,因此需要toString()后在转换成JSON对象,才能方位其内部的属性和方法
})
response2.on('end', () => {
resolve(info) // 在此时完成resolve,并将整个info对象传递到then(argument)中
})
})


then()


.then((infos) => {
let coursesData = []
infos.forEach((info) => {
let courses = filterChapters(info.html, info.numInfo) // 将该对象置于filterChapters函数中进行操作
coursesData.push(courses)
})
...
})


filterChatpers()
函数中把第二个参数(即获取的人数信息)进行赋值

function filterChapters(html, num) {
let $ = cheerio.load(html)
...
let number = num;
...
}


最后利用
fs
API将所有信息进行输出位一个
txt
文件

coursesData.sort((a, b) => b.number - a.number)// 根据听课人数从多到少进行排序
printCourseInfo(coursesData)


/*
* 创建txt文件
*/
fs.appendFile('courseData.txt', printInfo, 'utf-8', (err) => {
if(err) {
console.log(err)
}
console.log('文件添加成功!')
})


完整代码请移步 这儿

另:

1.该文件依赖 cheerio.js 记得npm安装这个包,方法为

npm i cheerio -s


2.代码更新日期为为 6th, Sept, 2017, 后期慕课网可能会修改页面结构,因此该demo不具备永久有效性(代码已然与教学视频时结构不同)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  node.js 爬虫 ajax