前言
最近几天在看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文件存储在本地。
注:本文内容来自互联网,旨在为开发者提供分享、交流的平台。如有涉及文章版权等事宜,请你联系站长进行处理。