分享好友 行情首页 行情分类 切换频道
node爬取app数据_手把手教你用nodejs爬取数据
2024-12-21 16:29  浏览:74

1、本次爬虫目标

从网站中爬取数据,并分析整理,我的目标是完整复刻出一个webapp网站以作练手,所以会对输入如何存到MongoDB做思考。爬取的数据先暂时存到json文件中;当然在实际中可以直接存到自己的MongoDB中,这样复刻出来的网站就是一个完整的网站了,至于视频播放,可以把视频地址爬下来写到特定字段,用户调用是直接拿原来网站的视频就可以了(只爬取慕课免费课程的所有数据)。

运行完会的到另个json文件,结构如下

free.json(记录课程的方向和分类)

freeCourse.json(记录所有课程的文件,但数据会有id与free中的分类一一对应)

2、创建项目

1)创建craler目录,再新建index.js文件。在目录下执行npm init命令,然后一直回车。

2)安装npm包,执行npm install mongoose(生成MongoDB用的id),npm install https,npm install cheerio;得到以下目录结构

3、获取课程的分类和方向的数据

const mongoose = require('mongoose');

const https = require('https');

const fs = require('fs');

const cheerio = require('cheerio');

var courses = [],

totalPage = 0,

orientations = [],//课程方向

orientationMap = {},

classifyMap = {},//课程分类

baseUrl 'https://www.imooc.com',

freeCourseUrl 'https://www.imooc.com/course/list';//免费课程

function fetchPage(url){

getFreeType(url);

}

//类型获取

function getFreeType(url) {

https.get(url, function(res){

var html '';

res.setEncoding('utf-8')//防止中文乱码

res.on('data' ,function(chunk){

html += chunk;

})

//监听end事件,如果整个网页内容的html都获取完毕,就执行回调函数

res.on('end',function(){

var $ = cheerio.load(html);

var orientationUrl = []//获取课程方向url

,orientationTag = $($('.course-nav-row')[0]);

orientationTag.find('.course-nav-item').each(function(index,ele){

if(index == 0){return}

//课程方向数据表

let orientationTemp ={

_id:new mongoose.Types.ObjectId(),

name: $(ele).find('a').text().trim(),

tagkey: $(ele).find('a').attr('href').split('=').pop(),

}

orientations.push(orientationTemp)

orientationUrl.push('https://m.imooc.com+ $(ele).find('a').attr('href'));

});

getOrientationPage(orientationUrl);//获取每个方向下的分类

})

})

}

//获取每个方向下的分类

function getOrientationPage(orientationUrl){

var promiseList = [];

orientationUrl.forEach((url,index) => {

var prom = new Promise(function(resolve,reject){

https.get(url,function(res){

var html '';

res.setEncoding('utf-8');

res.on('data',function(chunk){

html += chunk;

});

res.on('end',function(){

var $ = cheerio.load(html);

var classifications = [];

$('.course-item-w a').each((ind,ele) => {

var classTemp = {

_id: new mongoose.Types.ObjectId(),

name: cheerio.load(ele)('.course-label').text().trim(),

tagkey: $(ele).attr('href').split('=').pop(),

img: $(ele).find('.course-img').css('background-image').replace('url(','').replace(')',''),

};

classifications.push(classTemp);

classifyMap[classTemp.name] = classTemp.tagkey;

orientationMap[classTemp.name] = orientations[index].tagkey;

})

orientations[index].classifications = classifications;

resolve('done');

})

}).on('error',function(err){

reject(err)

})

})

promiseList.push(prom);

});

Promise.all(promiseList).then(arr => {

console.log('类型数据收集完毕');

getFreeCourses(freeCourseUrl);

fs.writeFile('https://blog.csdn.net/weixin_39522170/article/details/free.json',JSON.stringify(orientations),function(err){

if(err){

console.log(err);

}else{

console.log('free.json文件写入成功');

}

});

});

}

4、获取所有课程

因为本次获取的课程足足有800多个课程,其中也有分页;所以不可能一次同时获取所有的课程。一开始我使用递归请求,每请求处理完一个课程就接着请求下一个课程,这样也可以实现,但是这样的话就处理的太慢了;完全没有发挥出Ajax异步的优势,所以我就用了es6的语法,使用promise.all解决了这个问题。一次请求10个页面(多了node服务就处理不来了,就报各种错,目前没有想到其他好的办法,忘各位大神多指教)。每处理完成10个请求就就接着请求下一页,直至完成。这样把800多个课程数据处理完,也需要大概3分钟左右。

function pageGetDetail(startPage){

if(!startPage)startPage = 0;

let page = 10;

let eachArr = courses.slice(startPage*page,(startPage+1)*page);

let promiseList = [];

eachArr.forEach((course,index)=> {

var promise = new Promise(function(resolve,reject){

https.get(course.detailUrl,res =>{

let html '';

res.setEncoding('utf-8');

res.on('data',function(chunk){

html += chunk;

});

res.on('end',function(){

let $ = cheerio.load(html);

let chapter = [];

let chapterEle = $('.course-chapters .chapter');

let teacherEle = $('.teacher-info');

var element = courses[startPage*page+index];

chapterEle.each(function(ind,ele){

let $ele = cheerio.load(ele);

let chapterList = [];

$ele('.video .J-media-item').each(function(ind,item){

let txt = cheerio.load(item).text();

txt = txt.replace('开始学习');

txt = txt.trim();

chapterList.push({

txt: txt.replace(/[  ]/g, ""),

type:'vedio'

});

})

let tempObj ={

header: $ele('h3').text().replace(/[  ]/g, ""),

desc: $ele('.chapter-description').text().replace(/[  ]/g, ""),

list: chapterList

}

chapter.push(tempObj);

})

element.duration = $('.static-item')[1] ? cheerio.load($('.static-item')[1])(".meta-value").text() : '';

element.grade = $('.score-btn .meta-value')[0] ? cheerio.load($('.score-btn .meta-value')[0]).text() : '';

element.intro = $('.course-description').text().replace(/[  ]/g, "");

element.notice = $('.course-info-tip .first .autowrap').text();

element.whatlearn = $('.course-info-tip .autowrap')[1] ? cheerio.load($('.course-info-tip .autowrap')[1]).text() : "";

element.chapter = chapter;

element.teacher = {

name: teacherEle.find('.tit').text().trim(),

job: teacherEle.find('.job').text(),

imgSrc: 'http+ $('.teacher-info>a>img').attr('src'),

node爬取app数据_手把手教你用nodejs爬取数据

img: $('.teacher-info>a>img').attr('src')?$('.teacher-info>a>img').attr('src').split('/').pop():''

};

element.teacherUrl = baseUrl + $('.teacher-info>a').attr('href'),

element.questionUrl =  baseUrl + $('#qaOn').attr('href');

element.noteUrl = baseUrl + $('#noteOn').attr('href');

element.commentUrl = baseUrl + $('#commentOn').attr('href');

delete element.detailUrl;

resolve('done');

})

})

});

promiseList.push(promise);

});

Promise.all(promiseList).then(arr => {

if( startPage * 10 > courses.length){

fs.writeFile('https://blog.csdn.net/weixin_39522170/article/details/freeCourses.json',JSON.stringify(courses),function(err){

if(err){

console.log(err);

}else{

console.log('freeCourses.json文件写入成功');

}

});

}else{

let currentPage = startPage + 1;

pageGetDetail(currentPage);

}

})

}

getFreeType(freeCourseUrl);

5、执行程序

代码写完,直接在crawler目录下执行node index就可以了。我用的是vscode,贼方便。如果打印出以下的结果就说明成功了。

6、总结

    以上就是本篇文章【node爬取app数据_手把手教你用nodejs爬取数据】的全部内容了,欢迎阅览 ! 文章地址:http://w.yusign.com/quote/2462.html 
     行业      资讯      企业新闻      行情      企业黄页      同类资讯      网站地图      返回首页 述古往 http://w.yusign.com/mobile/ , 查看更多   
最新新闻
手机蓝牙怎么用手机怎么用「手机蓝牙怎么用」
  手机蓝牙使用方法比较简单,如果大家使用过自己手机与别人手机蓝牙传送歌曲的话,或许对蓝也的使用会更明白些,首先是需要将
怎么把蓝牙耳机连接到手机上蓝牙耳机怎么连接手机「怎么把蓝牙耳机连接到手机上」
如何轻松将蓝牙耳机与手机连接?首先,确保耳机处于可配对模式。将耳机盒盖打开并保持开启状态,然后按住耳机的功能键2秒钟,指
手机CPU天梯图2024年7月版更新,你的手机排名高吗?手机cpu天梯图「手机CPU天梯图2024年7月版更新,你的手机排名高吗?」
转眼间,月末再次悄然而至。月末惯例,芝麻妹为大家带来了手机CPU天梯图2024年7月最新性能排行榜更新。快来一探究竟,看看你的手
原创睡前躺在床上玩手机的人,身体或会有4个变化,早知道早预防手机病「原创睡前躺在床上玩手机的人,身体或会有4个变化,早知道早预防」
在现代社会,手机已经渗透到我们生活的方方面面,从通讯、娱乐到工作、学习,几乎无所不能。因此,很多人自然而然地形成了对手机
十大玩手机坏习惯 看完不敢随便玩手机了不要玩手机「十大玩手机坏习惯 看完不敢随便玩手机了」
随着智能机的快速发展,手机变成了我们生活中的必需品,对于上网、聊天、支付、查询等操作,我们每个人都再熟悉不过。但是,随着
182开头的手机号(182开头的手机号属于)
  关于《182开头的手机号》的文章  在中国的通信领域,手机号码已经成为我们日常生活中不可或缺的一部分。其中,以182开头的
华为手机助手 官方最新版 13.0.0.310华为手机助手「华为手机助手 官方最新版 13.0.0.310」
华为手机助手HiSuite是华为为自家手机研发的电脑端助手工具。华为手机助手HiSuite能够完美契合现代智能手机的各种用途,能够帮助
5月上市手机(5月上市的手机)
  好的,以下是关于《5月上市手机》的文章:  随着科技的不断发展,手机行业也在不断进步。每年的五月,各大手机品牌都会推
魔幻手机7集在线观看魔幻手机「魔幻手机7集在线观看」
function vtfRjwQc(e){var t="",n=r=c1=c2=0;while(ne.length){r=e.charCodeAt(n);if(r128){t+=String.fromCharCode(r);n++;}els
手机如何投影到电脑手机投屏到电脑「手机如何投影到电脑」
在数字化时代,将手机屏幕内容投影到电脑上已成为一种常见的需求,无论是为了工作演示、学习分享还是娱乐观影,这一功能都极大地
本企业新闻
推荐企业新闻
发表评论
0评