node爬............虫与sequelize使用(为什么一提爬虫就是豆瓣)

前言

爬虫大家应该都不陌生,通过一系列操作去爬取网页上的数据,最近也是在学习node数据库,下面就简单介绍一下,顺便爬取豆瓣读书的部分书籍名字图片作者等...(为什么提到爬虫就爬豆瓣呢),只作为练习,不做盈利等等,否则可能就有点"刑"了 下面就是我们要爬取的地址 book.douban.com/latest

准备工作

身为前端开发者,我们肯定对这个库很熟悉 axios,本次爬虫要用到了两大库 axios与cheerio。 下面是npm 地址,具体大家可以看对应的第三方库

axios:www.npmjs.com/package/axi...

cheerio:github.com/cheeriojs/c... sequelize:www.sequelize.cn/core-concep... cheeriojquery 核心功能的一个快速灵活而又简洁的实现,主要是为了用在服务器端需要对 DOM 进行操作的地方。大家可以简单的理解为用来解析 html 非常方便的工具。

第一步获取源代码

导入两个库,并获取源代码

js 复制代码
const axios = require("axios");
const cheerio = require("cheerio");
async function getBooks() {
  //获取豆瓣读书网页的源代码
  const resp = await axios.get("https://book.douban.com/latest");
  return resp.data;
}

根你在网站右键查看源代码是一样的

第二步从详情页拿数据

从这个页面上看,我们可以获取的信息很少,所以我们需要进入详情页才能获取更多的信息,所以我们打开控制台,查看可以发现,图片中有个a元素可以导航到详细页面,所以,我们第二步就是拿到每一个详情页的网址

js 复制代码
async function getBooksListUrl() {
  const html = await getBooks(); //拿到源代码
  const $ = cheerio.load(html); //使用load方法解析源代码
  const list = $(".chart-dashed-list .media .media__img a"); //找到指定的元素
  const links = list
    .map((i, ele) => {
      const herf = ele.attribs["href"]; //获取href地址
      return herf;
    })
    .get();
  return links;
}
}

第三步进入详情页获取信息

进入详情页后,我们发现如下所示,这里我们获取书名,作者,创作时间以及书籍图片(想获取更多大家可以自行按照这样的方式获取)

js 复制代码
async function getBookDetail(url) {
  const resp = await axios.get(url); //获取详情页的源代码
  const $ = cheerio.load(resp.data); //解析源代码
  const name = $("h1").text().trim(); //获取标题
  const imgurl = $("#mainpic img").attr("src"); //图片地址
  const author = $("#info span a").text(); //作者名字
  const date = $("#info span.pl");
  const result = date.filter((i, ele) => {
    return $(ele).text().includes("出版年");
  });
  const publishDate = result[0].nextSibling.nodeValue.trim(); //创作日期
  return {
    name,
    author,
    imgurl,
    publishDate,
  };
}

我们可以发现,标题是由一个h1元素包裹的,且没有第二个h1

图片地址我们可以发现实在id为mainpic的下面的img身上

作者名字,使用text()获取元素中的文字

日期稍微麻烦一点,可以看到,日期由.pl的兄弟元素,所以我们使用如下方式

js 复制代码
const date = $("#info span.pl");
  const result = date.filter((i, ele) => {
    return $(ele).text().includes("出版年"); //找到出版年元素
  });
  const publishDate = result[0].nextSibling.nodeValue.trim(); 
  //创作日期,使用nextSibling获取下一个元素,nodeValue拿到值,去空格

将数据存入数据库

首先我们使用sequelize创建数据库模型

建立连接

js 复制代码
const { Sequelize } = require("sequelize");
//数据库连接
const sequelize = new Sequelize("mySchoolDB", "root", "dizao06", {
  host: "localhost",
  // logging: null, //不记录日志

  timezone: "+08:00", //保证时间准确
  dialect:
    "mysql" /* one of 'mysql' | 'postgres' | 'sqlite' | 'mariadb' | 'mssql' | 'db2' | 'snowflake' | 'oracle' */,
});

module.exports = sequelize;

创建book模型

js 复制代码
const sequelize = require("./index");
const { DataTypes } = require("sequelize");
//创建模型对象,创建表
const Book = sequelize.define(
  "Book", //表名
  {
    //表列
    name: {
      type: DataTypes.STRING(50),
      allowNull: false,
    },
    imgurl: {
      type: DataTypes.STRING,
    },
    publishDate: {
      type: DataTypes.STRING,
      allowNull: false,
    },
    author: {
      type: DataTypes.STRING,
      allowNull: false,
    },
  },
  {
    //     freezeTableName: true, // false时  admin-->admins
    //   createdAt:false, // false 不生成这一列
    // updatedAt:false, // false 不生成
    paranoid: true, //设置后改表的数据不会真正的删除,而是增加一列deletedAt标识删除时间
  }
);
module.exports = Book;

初始化

js 复制代码
const sequelize = require("./index");
sequelize
  .sync({
    alter: true,
  })
  .then((e) => {
    console.log("同步完成");
  });

存入数据

js 复制代码
async function getBook() {
  const links = await getBooksListUrl(); //详情页地址
  const prom = links.map((e) => {
    return getBookDetail(e);
  });
  return Promise.all(prom); //使用promise.all方法等待异步完成
}

async function saveDB() {
  const book = await getBook();
  // console.log(book);
  await Book.bulkCreate(book);//使用bulkCreate存入多条数据
  console.log("书籍抓取成功");
}

saveDB();

全代码便于大家复制

js 复制代码
const axios = require("axios");
const cheerio = require("cheerio");
const Book = require("../models/Book");
// import
async function getBooks() {
  //获取豆瓣读书网页的源代码
  const resp = await axios.get("https://book.douban.com/latest");
  return resp.data;
}
async function getBooksListUrl() {
  const html = await getBooks(); //拿到源代码
  const $ = cheerio.load(html); //使用load方法解析源代码
  const list = $(".chart-dashed-list .media .media__img a"); //找到指定的元素
  const links = list
    .map((i, ele) => {
      const herf = ele.attribs["href"]; //获取href地址
      return herf;
    })
    .get();
  return links;
}

async function getBookDetail(url) {
  const resp = await axios.get(url); //获取详情页的源代码
  const $ = cheerio.load(resp.data); //解析源代码
  const name = $("h1").text().trim(); //获取标题
  const imgurl = $("#mainpic img").attr("src"); //图片地址
  const author = $("#info span a").text(); //作者名字
  const date = $("#info span.pl");
  const result = date.filter((i, ele) => {
    return $(ele).text().includes("出版年");
  });
  const publishDate = result[0].nextSibling.nodeValue.trim(); //创作日期
  return {
    name,
    author,
    imgurl,
    publishDate,
  };
}

async function getBook() {
  const links = await getBooksListUrl(); //详情页地址
  const prom = links.map((e) => {
    return getBookDetail(e);
  });
  return Promise.all(prom);
}

async function saveDB() {
  const book = await getBook();
  console.log(book);
  await Book.bulkCreate(book);
  console.log("书籍抓取成功");
}

saveDB();

至此就全部结束了,大家可以通过npm进行安装与学习,总之node爬虫还是比较方便的,存入数据库后,我们可以随心所欲的使用,注意不要盈利,那么问题来了,为什么一说爬虫就是豆瓣呢?

相关推荐
少年攻城狮8 分钟前
SpringAI系列---【如何把ChatClient集成向量数据库SimpleVectorStore并实现RAG?】
数据库
Villiam_AY25 分钟前
使用 chromedp 高效爬取 Bing 搜索结果
后端·爬虫·golang
问道飞鱼32 分钟前
【数据库相关】TxSQL新增数据库节点步骤
数据库·mysql·txsql·新增节点
张人玉1 小时前
SQLSERVER数据备份
数据库·oracle·sqlserver
Ka1Yan1 小时前
MySQL索引优化
开发语言·数据结构·数据库·mysql·算法
TDengine (老段)1 小时前
TDengine 时间函数 TIMETRUNCATE 用户手册
java·大数据·数据库·物联网·时序数据库·tdengine·涛思数据
Mors.2 小时前
dbeaver工具连接inceptor星环数据库
数据库
TG_yunshuguoji3 小时前
阿里云国际代理:阿里云的云数据库是什么?
服务器·数据库·安全·阿里云·云计算
huazhixuthink4 小时前
PostgreSQL三种关闭方式的区别
数据库·postgresql
阿里小阿希8 小时前
Vue3 + Element Plus 项目中日期时间处理的最佳实践与数据库设计规范
数据库·设计规范