用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. SQL Server的非聚集索引中会存储NULL吗?

    原文:SQL Server的非聚集索引中会存储NULL吗? SQL Server的非聚集索引中会存储NULL吗? 这是个很有意思的问题,下面通过如下的代码,来说明,到底会不会存储NULL. --1.建 ...

  2. 表单送件按钮代码(一)cs(C#)(未完)

    protected void BtnRequest_Clich(object sender, EventArgs e) { lblMsg.Text= " " ; lblfmsg.T ...

  3. 3_PHP表达式_4_PHP运算符

    以下为学习孔祥盛主编的<PHP编程基础与实例教程>(第二版)所做的笔记. 3.4.1 算术运算符 <?php $num1 = -10; $num2 = -4; $num3 = $nu ...

  4. source tree每次push都需要密码的解决方法

    Windows首先可以考虑使用GitHub for Windows,它已经包含了该助手,或者可以下载对应系统的版本:Windows 7.Windows 8.Source 版本,然后解压缩文件并将里面的 ...

  5. [LeetCode] 234. 回文链表 ☆(翻转链表)

    描述 请判断一个链表是否为回文链表. 示例 1: 输入: 1->2输出: false示例 2: 输入: 1->2->2->1输出: true 进阶:你能否用 O(n) 时间复杂 ...

  6. dubbo和mq的使用场景

    MQ:消息队列.生产者消费者模式,可用于对消息实时性要求不高的场景.多进程之间间接调用关系 Dubbo:RPC实现.多进程之间直接调用关系 dubbo 1,rpc的分布式集群支持:负载均衡是对外提供一 ...

  7. Python中@staticmethod和@classmethod的作用和区别

    简单介绍一下两者的区别: 对于一般的函数test(x),它跟类和类的实例没有任何关系,直接调用test(x)即可 #!/usr/bin/python # -*- coding:utf-8 -*- de ...

  8. MongoDB官方推荐的GUI工具-Compass的使用

    探索和操作MongoDB数据的最简单方法 用于MongoDB的GUI.可视化地查看数据.以秒为单位运行临时查询.使用完整的CRUD功能与数据交互.查看和优化查询性能.可在Linux.Mac或Windo ...

  9. C++——多态实现原理分析

    前言 虚函数执行速度要稍慢一些.为了实现多态性,每一个派生类中均要保存相应虚函数的入口地址表,函数的调用机制也是间接实现.所以多态性总是要付出一定代价,但通用性是一个更高的目标. 实验环境 Windo ...

  10. JS获取当前月份的最后一天

    <button onclick="function_name()">获取当前月份的最后一天</button> <script type="t ...