用nodeJs制作一个简单的网页爬虫

主要分为三个步骤,向目标请求数据,处理数据,打印数据。需要用到的模块有http,cheerio。

1.准备步骤,引入要使用的模块

2.向目标请求数据

http.get(url,function(res){
var html=''; res.on("data",function(data){
html+=data;
}) res.on("end",function(){
var couseData=filterChapter(html);//处理 printcouse(couseData);//打印
})
}).on("error",function(){
console.log("something is error")
})

知识点:res服务器响应有两个事件,data事件是数据传输时触发,如果数据量比较大的话,会将数据分为小段小段的接受,每次都会触发data事件。end事件,所有数据接受完毕时触发。

3.处理数据

function filterChapter(html){
var $=cheerio.load(html); var chapters=$(".chapter"); var couseData=[]; chapters.each(function(){
var chapter=$(this);
var chapterTil=chapter.find("strong").text();
var chapterCon=chapter.find(".video").children("li"); var chapterData={
chapterTil:chapterTil,
chapterCon:[]
}
chapterCon.each(function(){
var chapterDetail=$(this).find(".studyvideo");
var chapterDetailTil=chapterDetail.text();
var id=chapterDetail.attr("href").split("video/")[1]; chapterData.chapterCon.push({
title:chapterDetailTil,
id:id
})
}) couseData.push(chapterData)
}) return couseData; }

知识点:cheerio模块几乎能够解析任何的 HTML 和 XML document,并用jquery来进行dom操作。它为服务器特别定制的,快速、灵活、实施的jQuery核心实现。

在这里是要找到课程章节名称及子栏目

4.打印数据

function printcouse(couseData){
couseData.forEach(function(item){
chapterTil=item.chapterTil; console.log(chapterTil+"\n"); item.chapterCon.forEach(function(chapterDetail){
console.log(chapterDetail.id+chapterDetail.title+"\n")
})
})
}

以上只能抓取一个页面的课程数据,接下来是要在此基础上抓取多个页面的数据。

增加模块promise

1.对请求数据部分的处理,改成返回一个promise对象,方便后续的并发控制

function getPageAsync(url){
return new Promise(function(resolve,reject){
console.log("正在爬取课程") http.get(url,function(res){
var html=''; res.on("data",function(data){
html+=data;
}) res.on("end",function(){
resolve(html)//resolve就是promise对象接下来要回调的函数
})
}).on("error",function(e){
reject(e)
console.log("something is error")
})
})
}

2.根据不同的url返回promise对象,将他们都放到数组里面

var videoIds=[348,259,197,75];
var fetchCouseArr=[];//promiser对象数组
videoIds.forEach(function(id){
fetchCouseArr.push(getPageAsync(baseUrl+id))//存入数组
})

3.并发控制,同时抓取多个页面数组

Promise
.all(fetchCouseArr)//all方法接受一个数组,返回多个promise对象,每个promise对象都执行接下来的操作
.then(function(pages){//pages就是每个要去爬的页面
var cousesData=[] pages.forEach(function(pages){
var courses=filterChapter(pages)//数据处理 cousesData.push(courses)
}) cousesData.sort(function(a,b){
return a.number<b.number
}) printcouse(cousesData)//数据打印
})

知识点:promise的all方法接受一个数组参数,对于数组内的每个promise对象都执行接下来的操作,上面请求数据时最后返回的reslove(html)在这里就是then方法内的回调函数,pages参数就是请求到的html数据。

4.数据处理和数据打印原理还是和最开始一样

function filterChapter(html){
var $=cheerio.load(html); var Title=$("#main .path>a").eq(3).children("span").text(); var number=parseInt($(".meta-value").eq(2).children("strong").text(),10); var couseData={
Title:Title,
videos:[],
number:number
}; var chapters=$(".chapter"); chapters.each(function(){
var chapter=$(this);
var chapterTil=chapter.find("strong").text();
var chapterCon=chapter.find(".video").children("li"); var chapterData={
chapterTil:chapterTil,
chapterCon:[]
}
chapterCon.each(function(){
var chapterDetail=$(this).find(".studyvideo");
var chapterDetailTil=chapterDetail.text();
var id=chapterDetail.attr("href").split("video/")[1]; chapterData.chapterCon.push({
title:chapterDetailTil,
id:id
})
}) couseData.videos.push(chapterData)
}) return couseData; } function printcouse(cousesData){
cousesData.forEach(function(courseData){
console.log(courseData.number+'人学过'+courseData.Title+'\n')
}) cousesData.forEach(function(courseData){
console.log('###'+courseData.Title+'\n') courseData.videos.forEach(function(item)
{
//console.log('###'+item.chapterTil+'\n')
var chapterTil=item.chapterTil; console.log(chapterTil+"\n"); item.chapterCon.forEach(function(chapterDetail){
console.log(chapterDetail.id+chapterDetail.title+"\n")
})
})
})
}

nodejs爬虫案例笔记的更多相关文章

  1. nodejs爬虫笔记(三)---爬取YouTube网站上的视频信息

    思路:通过笔记(二)中代理的设置,已经可以对YouTube的信息进行爬取了,这几天想着爬取网站下的视频信息.通过分析YouTube,发现可以从订阅号入手,先选择几个订阅号,然后爬取订阅号里面的视频分类 ...

  2. nodejs爬虫笔记(二)---代理设置

    node爬虫代理设置 最近想爬取YouTube上面的视频信息,利用nodejs爬虫笔记(一)的方法,代码和错误如下 var request = require('request'); var chee ...

  3. nodejs爬虫--抓取CSDN某用户全部文章

    最近正在学习node.js,就像搞一些东西来玩玩,于是这个简单的爬虫就诞生了. 准备工作 node.js爬虫肯定要先安装node.js环境 创建一个文件夹 在该文件夹打开命令行,执行npm init初 ...

  4. NodeJS 爬虫爬取LOL英雄联盟的英雄信息,批量下载英雄壁纸

    工欲善其事,必先利其器,会用各种模块非常重要. 1.模块使用 (1)superagent:Nodejs中的http请求库(每个语言都有无数个,java的okhttp,OC的afnetworking) ...

  5. Nodejs爬虫进阶教程之异步并发控制

    Nodejs爬虫进阶教程之异步并发控制 之前写了个现在看来很不完美的小爬虫,很多地方没有处理好,比如说在知乎点开一个问题的时候,它的所有回答并不是全部加载好了的,当你拉到回答的尾部时,点击加载更多,回 ...

  6. NodeJS爬虫系统初探

    NodeJS爬虫系统 NodeJS爬虫系统 0. 概论 爬虫是一种自动获取网页内容的程序.是搜索引擎的重要组成部分,因此搜索引擎优化很大程度上是针对爬虫而做出的优化. robots.txt是一个文本文 ...

  7. 关于Python网络爬虫实战笔记③

    Python网络爬虫实战笔记③如何下载韩寒博客文章 Python网络爬虫实战笔记③如何下载韩寒博客文章 target:下载全部的文章 1. 博客列表页面规则 也就是, http://blog.sina ...

  8. python网络爬虫学习笔记

    python网络爬虫学习笔记 By 钟桓 9月 4 2014 更新日期:9月 4 2014 文章文件夹 1. 介绍: 2. 从简单语句中開始: 3. 传送数据给server 4. HTTP头-描写叙述 ...

  9. nodejs爬虫——汽车之家所有车型数据

    应用介绍 项目Github地址:https://github.com/iNuanfeng/node-spider/ nodejs爬虫,爬取汽车之家(http://www.autohome.com.cn ...

随机推荐

  1. iis 经典模式和集成模式

    IIS7.0中的Web应用程序有两种配置模式:经典模式和集成模式.两者区别大家可以参考下,根据实际情况选用.  经典模式是为了与之前的版本兼容,使用ISAPI扩展来调用ASP.NET运行库,原先运行于 ...

  2. 【转载】C#将字符串中字母全部转换为大写或者小写

    在C#的编程开发过程中,有时候判断字符串是否相等时,并不关注字母的大小写,此时在C#中可以使用ToUpper方法将字符串中所有的字母转换为大写,使用ToLower方法可以将字符串中所有字母转换为小写. ...

  3. jquery判断数据类型源码解读

    var class2type = {}; ("Boolean Number String Function Array Date RegExp Object Error").spl ...

  4. ArduPilot存储管理 Storage EEPROM Flash

    AP_HAL::Storage 此类可以应用于所有平台.PX4v1平台支持8k的EEPROM,Pixhawk平台支持16k的FRAM铁电存储器 存储大小定义:libraries/AP_HAL/AP_H ...

  5. [原]Object-Oriented Programming With ANSI-C

    前一段时间面试被问到一个问题,怎么用C去实现面向对象的特性,比如封装.继承和多态.我心想这不是闲的蛋疼么,好吧,我承认我不会...[大哭].然后去网上找相关的文章,有文章推荐了<Object-O ...

  6. zookeeper安装简要步骤

    vi zoo.cfg1.dataDir=/var/zookeeper2.server.1=zoo1:2888:3888server.2=zoo2:2888:3888server.3=zoo3:2888 ...

  7. LNMP环境搭建之编译安装指南(php-5.3.27.tar.gz)

    测试环境:CentOS release 6.5 (Final) 软件安装:nginx   mysql-5.5.32-linux2.6-x86_64.tar.gz   php-5.3.27.tar.gz ...

  8. Android笔记(二十四) Android中的SeekBar(拖动条)

    拖动条和进度条非常相似,只是进度条采用颜色填充来表明进度完成的程度,而拖动条则通过滑块的位置来标识数值——而且拖动条允许用户拖动滑块来改变值,因此拖动条通常用于对系统的某种数值进行调节,比如调节音量等 ...

  9. 【TestNG】使用代码方式调用TestNG用例执行

    TestNG的用例除了直接运行之外,还可以使用代码来调用,这样做的好处在于我们可以将其嵌入其他代码中,来执行这些TestNG用例,方法如下: 1.直接调用用例类 范例:定义了两个测试用例类为Depen ...

  10. IPC——概述

    现代操作系统下的内存 现在的OS都引入了虚拟内存机制.我们说的内存空间,实际上虚拟内存空间,CPU执行PC指向的命令,PC指向的就是虚拟内存空间地址.虚拟内存机制只不过是OS为我们做了一层虚拟内存地址 ...