在node.js出现之后,我们也可以使用JavaScript来实现爬虫了,对应于http和https,我们只要引入http或者https模块就可以爬取对应的数据,在爬取文章数据后我们将其保存到本地文件中,首先导入三个模块
导入模块
这里要导入三个模块,
https:用于实现爬虫
cheerio:用于处理数据
fs:用于将数据写入本地文件中
const https = require("https")
const cheerio = require("cheerio")
const fs = require("fs")
获取数据
爬虫是在获取数据后根据我们的需要,分离出一部分数据,所以首先,我们需要获取页面的数据。 将首页放入一个变量中存储,使用https的get方法获取页面的数据。
const url = "";
// 获取数据
https.get(url, res => {
// 成功的回调函数
}).on("error", err => {
// 失败的回调函数
})
可以通过console将内容打印到控制台来获取响应的部分信息,通过返回的状态码我们就可以得知是否成功得到响应了。
const url = "";
// 获取数据
https.get(url, res => {
// 成功的回调函数
console.log("res.statusCode:", res.statusCode);
}).on("error", err => {
// 失败的回调函数
})
结果返回200说明得到正常的响应,接下来就开始获取页面显示的数据,由于http/https协议中,数据是一段发过来的,所以我们要监听发送并接受
https.get(url, res => {
// 成功的回调函数
// 打印状态码
// console.log("res.statusCode:", res.statusCode);
// 监听发送
res.on("data", chunk => {
console.log("chunk:", chunk);
})
}).on("error", err => {
// 失败的回调函数
})
这里可以看到数据以二进制的形式展现出来,这是因为数据是以流的形式传送过来的,此时,我们要做的是将数据装为我们平时看到的形式,同时将多个段拼接起来,这两个工作,可以直接由拼接字符串来完成。拼接完后我们再次打印出数据
可以看到此时的数据已经变成了我们熟悉的数据了
数据处理
现在数据已经收集完成了,接下来要进行数据的处理,监听数据的接收,当数据接收完毕时对数据进行处理
// 数据收集完毕
res.on("end",()=>{
})
要获取首页的文章内容,首先要得到文章内容所在的url,我们通过使用cheerio模块,匹配出我们要的a标签,然后获取标签对应的href,即是文章所在的url
cheerio模块可以使用jQuery的语法来匹配对应的标签,具体用法:cheerio的用法
res.on("end", () => {
let $ = cheerio.load(data);
// 使用f12控制台找出标题,再用jQuery语法匹配
$("main ul.feedlist_mod li .list_con h2 a").each(function() {
// 打印对应的href
console.log($(this).attr("href"))
})
})
函数封装
我们获取到了文章所在的url,所以要对这些url进行相应的get请求,当然我们不可能重复写上面的内容,所以将上面的内容封装成一个函数来调用
// 封装方法
function httpsGet(url, callback) {
https.get(url, res => {
let data = "";
res.on("data", (chunk) => {
data += chunk;
})
res.on("end", () => {
let $ = cheerio.load(data);
callback($)
})
}).on("error", (err) => {
console.log(err.message);
})
}
// 调用方法
httpsGet(url, function($) {
$("main ul.feedlist_mod li .list_con h2 a").each(function() {
let blogUrl = $(this).attr("href");
httpsGet(blogUrl, function($) {
// 打印所有的文章内容
console.log($("#article_content").text());
})
})
})
写入本地文件
到这里我们已经成功地得到了文章的内容了,最后一步将内容写入本地文件中,我们以文章的标题为文件名,使用fs模块的writeFileSync方法,写入txt文件中
// 调用方法
httpsGet(url, function($) {
$("main ul.feedlist_mod li .list_con h2 a").each(function() {
let blogUrl = $(this).attr("href");
httpsGet(blogUrl, function($) {
// 打印所有的文章内容
// console.log($("#article_content").text());
// 文章标题
let title = $("main div.blog-content-box .article-header-box .article-header div.article-title-box .title-article").text();
// 文章内容
let content = $("#article_content").text();
// 写入本地
fs.writeFileSync(`./blog/${title}.txt`, content)
})
})
})
可以看到文章已经被保留到本地了
完整代码
const https = require("https");
const cheerio = require("cheerio")
const fs = require("fs")
const url = "";
// // 获取数据
// https.get(url, res => {
// // 成功的回调函数
// // 打印状态码
// // console.log("res.statusCode:", res.statusCode);
// // 初始化数据字符串
// let data = "";
// // 监听发送
// res.on("data", chunk => {
// // console.log("chunk:", chunk);
// data += chunk;
// // console.log(data);
// })
// // 数据收集完毕
// res.on("end", () => {
// let $ = cheerio.load(data);
// // 使用f12控制台找出标题,再用jQuery语法匹配
// $("main ul.feedlist_mod li .list_con h2 a").each(function() {
// // 打印对应的href
// console.log($(this).attr("href"))
// })
// })
// }).on("error", err => {
// // 失败的回调函数
// })
// 封装方法
function httpsGet(url, callback) {
https.get(url, res => {
let data = "";
res.on("data", (chunk) => {
data += chunk;
})
res.on("end", () => {
let $ = cheerio.load(data);
callback($)
})
}).on("error", (err) => {
console.log(err.message);
})
}
// 调用方法
httpsGet(url, function($) {
$("main ul.feedlist_mod li .list_con h2 a").each(function() {
let blogUrl = $(this).attr("href");
httpsGet(blogUrl, function($) {
// 打印所有的文章内容
// console.log($("#article_content").text());
// 文章标题
let title = $("main div.blog-content-box .article-header-box .article-header div.article-title-box .title-article").text();
// 文章内容
let content = $("#article_content").text();
// 写入本地
fs.writeFileSync(`./blog/${title}.txt`, content)
})
})
})