小书虫app日记——(2)

本文介绍如何搭建一个简单的小说搜索引擎,包括爬虫功能的实现及页面解析等步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

上一篇中,把前端试图部分的架子搭了出来,这一篇我们转换下思路从后台入手,思考一下小书虫到底能做些什么,既然叫做小书虫app,构想之初就是:app的主要内容来源为网络啦,所以这篇实现一个爬虫功能,配合视图部分做成一个简单的小说搜索引擎。
我们首先找一个地方放置我们的后台项目,cd进入项目文件夹npm init初始化一个项目,并npm install需要的模块,这里先安装request(负责http请求)、cheerio(网页解析)、bluebird(promise模块处理异步)

然后就开始编辑入口文件了,默认是index.js,我改成app.js(或者entry.js都行)引入模块:

var request = require('request');//http请求
var Promise = require("bluebird");//promise模块处理异步
var cheerio = require('cheerio');//网页解析

接下来就找个网站爬爬看,既然是书虫这里就找起点中文网吧,打开起点首页,点击全部小说就进入到所有小说放置的网页了,考虑到是为搜索引擎做准备我打算只爬到书籍的书名和链接,这样最大化简化的我们的速度,F12或者反键查看元素定位到书名的源码可以看到:
这里写图片描述

<a href="//book.qidian.com/info/1004608738" target="_blank" data-eid="qd_B58" data-bid="1004608738">圣墟</a>

可以看到,每个书名和其链接都是如上的a标签,因此我们就能通过其选择器$('.book-mid-info h4 a') 来定位这个元素,为保证正确可以在浏览器提供的环境里测试一下(自带jQuery选择器):
这里写图片描述
测试发现正确输出了我们想要的a标签,再观察页面地址,和布局,得知每一页20部小说,共4万多页,包含了起点的所有小说,到这里我们大概了解了基本规则:

var request = require('request');
var Promise = require("bluebird");
var cheerio = require('cheerio');

//起点中文网
var baseUrl = "https://www.qidian.com/all?orderId=&style=1&pageSize=20&siteid=1&pubflag=0&hiddenField=0&page=";
var QiDianPages = 49145;
var rule = '.book-mid-info h4 a';

现在开始爬取页面,编写一个爬取方法,传入基本路径和页面参数组合成地址进行爬取,爬取使用request模块进行http请求,使用promise来进行异步优化,考虑好之后我们就可以编写了:

//爬取页面
function HtmlCrawl(baseUrl,page) {
  //使用Promise对象确保异步的爬取顺利进行
  return new Promise(function (resolve,reject) {
    var url = baseUrl + page;
    console.log("爬取地址:" + url);
    request(url,function (error, response, body) {
      if (!error && response.statusCode == 200) {
        resolve(body)
      }else {
        reject(error)
      }
    });
  });
}

通过HtmlCrawl方法返回的的页面实际上是一大串html,我们无法进行操作,所以就要借助cheerio,它自带的选择器就像jQuery一样能帮助我们解析定位到我们想要的内容,所以下面编写cheerio解析方法:

//页面解析
function CheerioFilter(page,rule) {
  var $ = cheerio.load(page); //当前的$符相当于拿到了所有的body里面的选择器
  var nameEles = $(rule);
  var dataArray = [];
  console.log(nameEles);
  for (var i = 0; i < nameEles.length; i++) {
    var obj = new Object();
    obj.tilte = nameEles[i].children[0].data;
    obj.link = "https:" + nameEles[i].attribs.href;
    dataArray.push(obj);
  }
  return dataArray;
}

CheerioFilter方法传入两个参数,要解析的页面、解析规则(前面我们已经找到),将解析好的内容过滤成我们想要的书名和链接后保存成对象push到数组中,最后返回数组,就完成了解析了。

下面测试一下我们的编码效果,起点有4万多页,我们先测试小一些,几十页看看,创建一个数组放置返回的promise对象数组,循环执行爬虫函数爬到每一页,然后返回的结果存到数组中,再来开始promise链:

var promiseObjectArray = [];
for (var i = 1; i <= QiDianPages; i++) {
  promiseObjectArray.push(HtmlCrawl(baseUrl,i));
}
Promise
  .all(promiseObjectArray)
  .then(function (pages) {
    var result = [];
    pages.forEach(function (html) {
      var bookItem = CheerioFilter(html,rule);
      result.push(bookItem);
    });
    console.log(result[0]);
    console.log(result[0].length);
  })

在拿到页面数据后再解析页面保存到最终数组,就完成了基本爬取了,看看运行效果:
这里写图片描述
测试一下后发现速度还是很快的,使用promise不仅优化了爬取的速度,还优化了我们的代码风格

这一篇就到这里,这一篇完成爬虫后下面就可以写匹配查询了,合起来就是一个简易的搜索引擎,下篇再搞。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值