基于Node 的爬虫

// superagent 是用来发起请求的,是一个轻量的,渐进式的ajax api,可读性好,学习曲线低,内部依赖nodejs原生的请求api,适用于nodejs环境下.,也可以使用http发起请求
// superagent-charset防止爬取下来的数据乱码,更改字符格式
// cheerio为服务器特别定制的,快速、灵活、实施的jQuery核心实现.。

const superagent = require("superagent");
const charset = require("superagent-charset");
charset(superagent);
const cheerio = require("cheerio");
const fs = require("fs");

/**
 * 批量采集图片类
 * @params String url 链接
 * @params Number pageStart 起始页
 * @params String charset 页面编码
 * @params Number pageStep 步长
 * @params Number pageTotal 总页面数
 */
class ReptilePic {
  constructor(url, pageStart, charset, pageStep, pageTotal) {
    this.url = url;
    this.pageStart = pageStart || 1;
    this.charset = charset || "utf8";
    this.pageStep = pageStep || 1;
    this.pageTotal = pageTotal || 1;
    this.pageLists = []; //页面链接集合
    this.picLists = []; //图片集合
    this.init();
  }
  init() {
    //1.生成列表页面link
    this.getPageList();
    //2.请求每个列表页面,生成图片list
    //3.下载图片(校验目录+保存)
  }
  /**
   * 生成列表页面link[]
   * 匹配(*) 替换为动态页面中的变量 可以是0-9 a-z A-Z
   * 后期加入循环多个变量 匹配功能
   */
  getPageList() {
    let reg = /\((\*)\)/g;
    if (reg.test(this.url)) {
      //   console.log("11------------", RegExp.$1); //*
      let len = parseInt(this.pageTotal / this.pageStep);
      for (let i = this.pageStart; i <= len; i += this.pageStep) {
        this.pageLists.push(this.url.replace(reg, i));
      }
      //   console.log("pageList----------", this.pageLists);
      console.log("生成列表list完成");
      console.log("开始采集图片地址list");
      this.getPicList(0);
    }
  }
  //2.请求每个列表页面,生成图片list
  getPicList(num) {
    // this.pageLists
    if (num > this.pageLists.length - 1) {
      console.log("生成图片list完成");
      console.log("开始下载图片");
      this.downLoadPic(0);
      return;
    } else {
      superagent
        .get(this.pageLists[num])
        .buffer(true)
        .charset(this.charset)
        .end((err, response) => {
          if (err) throw err;
          var $ = cheerio.load(response.text);
          //采集规则(可提出来自定义)
          $("div.g-main-bg ul.g-gxlist-imgbox li a").each((idx, element) => {
            let $element = $(element);
            let title = $(element).attr("title");
            let imgSrc = $element.find("img").attr("src");
            this.picLists.push({
              title,
              imgSrc,
            });
          });
          console.log(`开始采集第${num + 1}页图片地址`);
          num++;
          this.getPicList(num);
        });
    }
  }
  //3.下载图片(校验目录+保存)
  downLoadPic(index) {
    //批量下载图片
    //1.创建目录(后期自定义目录和文件名)
    /*     let dir = __dirname + "/imgs";
    fs.mkdir(dir, { recursive: true }, (err) => {
      if (err) throw err;
    }); */

    //2.下载  this.picLists = item   index下标
    if (index > this.picLists.length - 1) {
      console.log("批量下载图片完成");
      return;
    } else {
      let imgSrc = this.picLists[index].imgSrc;
      let dir = __dirname + "/imgs";
      let ws = fs.createWriteStream(
        dir + `/${this.picLists[index].title}${index}.png`
      ); //这里为了省事,我就直接用下标命名了;
      if (imgSrc.indexOf("http") !== -1) {
        superagent(imgSrc).pipe(ws);
      }
      ws.on("finish", () => {
        console.log(`${this.picLists[index].title}-----------下载完成`);
        index++
        this.downLoadPic(index)
      });
    }
  }
}



let url = "https://www.qqtn.com/tx/weixintx_(*).html";
new ReptilePic(url, 1, "gb2312", 1, 4);

 

posted @ 2021-01-13 15:40  奔跑的太阳花  阅读(128)  评论(0编辑  收藏  举报