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

来源:互联网 发布:www.47es.com最新域名 编辑:程序博客网 时间:2024/05/22 08:26

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

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

  1. 慕课重新搭建了网页结构,标签及其类名发生变动
  2. 观看人数由最初写在页面内部能够通过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不具备永久有效性(代码已然与教学视频时结构不同)

原创粉丝点击