nodejs爬虫的使用

459 阅读2分钟

先理清思路:

1、首先要明确要爬取的信息,

2、接着找到目标网站(该网站得有你需要的信息),

3、然后写代码,使用服务端去请求目标网页,获取目标网页后,使用类似jqury的方式,获取dom节点中的内容,将内容保存起来,可以返回,可以写进文件中

重点是写代码阶段,比如我之前写过得一个爬取小说网站的小说

使用nodejs爬虫,主要用到的技术有

request-promise、iconv-lite、cheerio

request-promise

是在服务端去请求url地址,如果是服务端渲染,返回的就是一个网页,我们就要这中网页的信息,就在这网页上拿到我们要的数据

iconv-lite

这是用来网页解码的,因为有的网页,使用request-promise拿到的是一堆乱码的数据,这时候我们就可以使用iconv-lite进行解码成我们看得懂的内容~_~。

cheerio

cheerio是jquery核心功能的一个快速灵活而又简洁的实现,主要是为了用在服务器端需要对DOM进行操作的地方。

然后看代码实现

// 小说爬虫
var express = require('express');
var router = express.Router();
var rp = require('request-promise');
var iconv = require('iconv-lite');
var cheerio = require('cheerio');

var { savejson, loadjson } = require('../utils')
router.get('/getBookList', async (req, res, next) => {
  // 小说列表url
  let url = 'https://www.zwdu.com/quanben/4.html'
  let $ = await rp({
    url,
    encoding: null,
    transform: body => cheerio.load(iconv.decode(body, 'gb2312'))
  });
  var boookArr = [];
  var $bookList = $('#main .novelslist2 ul li:nth-of-type(n+2)');
  $bookList.each((i, el) => {
    var $book = $(el).find('.s2 a');
 // 每个章节的dom
    let name = $book.text().trim() // 小说名
    let uri = 'https://www.zwdu.com' + $book.attr('href').trim() // 小说uri
    let type = $(el).find('.s1 a').text().trim() // 小说分类
    let author = $(el).find('.s4').text().trim()  // 小说作者
    boookArr.push({ name: name, author: author, type: type, uri: uri });
  });
  for (var i = 0; i < boookArr.length; i++) { 
   console.log('开始获取' + boookArr[i].name + '的章节目录');
    getChapter(boookArr[i])    console.log('-----------------分割线-----------------------')
  }
  console.log('***************本页小说获取完成****************');});

// 获取章节列表url 并执行获取章节目录页面
let getChapter = async (book) => {
  let curbook = JSON.parse(JSON.stringify(book))
  let uri = curbook.uri
  try {
    let $ = await rp({
      uri,
      encoding: null,
      transform: body => cheerio.load(iconv.decode(body, 'gb2312'))
    });
    let chapterArr = [];
    curbook.cover = $('#fmimg img').attr('src')
    curbook.description = $('#intro p:first').text()
    let $bookList = $('.box_con #list dl dd');
    $bookList.each((i, el) => {
      let index = i + 1;
      let $book = $(el).find('a'); // 每个章节的dom
      // 小说章节名
      let name = $book.text().trim()
      // 小说章节uri
      let uri = 'https://www.zwdu.com' + $book.attr('href').trim()
      chapterArr.push({ chapter_index: index, chapter_name: name, uri: uri });
    });
    console.log(curbook.name + '章节目录获取成功');
    curbook.chapter = chapterArr    // 保存小说
    console.log('保存' + curbook.name + '到文件中');
    await savejson(__dirname + `\\bookList\\${curbook.name}.json`, curbook);
    console.log('保存' + curbook.name + '到文件中,成功')
    // return book
  } catch (error) {
    console.log(error);
  }}

module.exports = router;

保存文件和读取文件的方法 savejson/loadjson

utils/index.js

var iconv = require('iconv-lite');
var fs = require('fs');
// 读取json文件 返回json数据
function loadjson(filepath) {
  console.log('filepath',filepath);
  var data;
  try {
    var jsondata = iconv.decode(fs.readFileSync(filepath, "binary"), "utf8");
    data = JSON.parse(jsondata);
  }  catch (err) {
    console.log(err);
  }
  return data;
}

// 将json数据 保存为json文件
 const savejson = async(filepath, data)=> {
 var datastr = JSON.stringify(data, null, 4);
  if (datastr) {
    try {
      fs.writeFileSync(filepath, datastr);
    }    catch (err) {
      console.log(err);
    }
  }}
module.exports = {  loadjson,  savejson}

这里只实现了爬取到小说章节列表截止,章节详情由于还要再请求一次网页,相当费时间,暂时没加进来了。

完整代码 GitHub地址:github.com/cloud-mouse…