前言
最近几天在看node.js方面的东西,想着结合一些小实例进行学习,这样可以更好的掌握所学的内容。于是就定了一个小demo,爬取点我达技术博客上面的文章标题+文章作者+发布时间。有不对的地方欢迎指正。
环境搭建
- 下载node.js
- 下载webStorm 这两个东西的下载网上都有很详细的下载过程。
需要的一些基础知识
- html
- javascript
- jquery
- node.js
创建项目
- 进入到项目存放的路径下
- mkdir dirname 创建文件夹
- cd dirname 进入文件夹路径
- npm init 初始化项目
如果没有特殊的要求,接下去的过程可以一路回车键,这样就可以完成项目的初始化过程了 - 安装cheerio包
npm install cheerio - 在dirname中创建一个js文件用于编写代码
cheerio
- 为服务器特别定制的,快速、灵活、实施的jQuery核心实现
- Cheerio 包括了 jQuery 核心的子集。Cheerio 从jQuery库中去除了所有 DOM不一致性和浏览器尴尬的部分,揭示了它真正优雅的API
- Cheerio 工作在一个非常简单,一致的DOM模型之上。解析,操作,呈送都变得难以置信的高效。基础的端到端的基准测试显示Cheerio 大约比JSDOM快八倍(8x)
- Cheerio 封装了兼容的htmlparser。Cheerio 几乎能够解析任何的 HTML 和 XML document
<1> 首先来点我达技术博客网站看下html文档的结构
我们需要title,author和time,因此不难可以找到网页中的元素。

如上图所示,我们所需要的属性都被找到了!
<2> 从找到的标签,可以比较简单的写出得到这些属性的代码。
1)获取title
var title = $(".post-title a:first-child");
2)获取author
var author = $(".post-meta a:first-child");
3)获取time
var time = $(".post-date");
这样,我们就分别得到了三个存储这属性标签的数组。由于得到的都是元素的数组,因此我们需要定义三个字符串数组分别来存储这三个元素中的内容。
author.each(function () { authorArray.push($(this).text()); }); time.each(function () { timeArray.push($(this).text()); }); title.each(function () { titleArray.push($(this).text()); });
这样,我们就将一个页面中的所有的title,time,author都存到了三个数组中。但是,点我达技术博客是分页的,会有很多个页面,这个时候光读取一个页面是远远不够的。接下去我们继续分析html代码。比较页面和最后一个页面,我发现最后一个页面少了一个元素。代码如下

没错,就是类名为older-posts的a标签,所以我们可以通过判断页面是否存在older-posts标签来确定是否存在下一页,若有下一页,则进入进入下一页再读取数据。
<3> 因此,在页面存在older-posts标签的时候,则获取到标签中的href属性,同时进入到下个页面。代码如下
if ($(".older-posts").length > 0) { var nextUrl = $(".older-posts").attr("href"); var newUrl = url.substring(0, 24); startSpider(newUrl + nextUrl);//startSpider()是开启爬取数据的函数 }
<4> 最后我们只需要将全局的三个存储着title,author和time的三个字符串连在一起,打印出来就可以了。
function test() { for (var i = 0; i < titleArray.length; i++) { console.log(titleArray[i]+":"+timeArray[i]+":"+authorArray[i]); } }
这样,整个过程就完成了。下面是完整的代码。
/** * Created by glc on 2017/9/20. */ var http = require("http"); var fs = require("fs"); var cheerio = require("cheerio"); var url = "http://tech.dianwoda.com"; var authorArray = new Array();//存储作者的名称数组 var titleArray = new Array();//存储文章标题数组 var timeArray = new Array();//存储发表时间数组 function startSpider(url) { http.get(url, function (res) { var html = "";//存储网页html res.setEncoding("utf-8"); //监听获取到数据 res.on("data", function (data) { html += data; }) res.on("end", function () { var $ = cheerio.load(html); var author = $(".post-meta a:first-child"); var time = $(".post-date"); var title = $(".post-title a:first-child"); author.each(function () { authorArray.push($(this).text()); }); time.each(function () { timeArray.push($(this).text()); }); title.each(function () { titleArray.push($(this).text()); }) if ($(".older-posts").length > 0) { var nextUrl = $(".older-posts").attr("href"); var newUrl = url.substring(0, 24); startSpider(newUrl + nextUrl); } }) } ) } startSpider(url) setTimeout(test,2000);//因为网络请求会消耗时间,会导致异步执行,这里阻塞2秒钟,再执行test方法。 function test() { for (var i = 0; i < titleArray.length; i++) { console.log(titleArray[i]+":"+timeArray[i]+":"+authorArray[i]); } }
总结:虽然这个项目非常的简单,但是在完成这个项目的时候,对于jquery操作dom和nodejs有了更好的掌握。
下一篇,是将每一篇文章全部抓取出来,以作者-时间-标题为文件名,以txt文件存储在本地。
注:本文内容来自互联网,旨在为开发者提供分享、交流的平台。如有涉及文章版权等事宜,请你联系站长进行处理。