《高阶前端指北》之JavaScript爬虫速成-数据存储(第三弹)

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第11天,点击查看活动详情

连接数据库

通常情况下,我们会爬取一些结构化的数据,通过建立表关系存储数据,数据库是必不可少。这里我们选择身材苗条,丰满的MySQL,当然你也可以选择婀娜多姿的MongoDB
动手能力强的直接,本地安装mysql了,安装教程遍地都是,自己search吧。想要简单学习,快速掌握原理的可以选择云数据库(免费版).

然后简单封装一下mysql.js

const mysql = require("mysql");
const connection = mysql.createConnection({
  host: "",
  user: "",
  port: 3306,
  password: "",
  database: "",
  charset: "utf8",
});
// 连接数据库
connection.connect();
// 封装插入语句,通常情况下插入较多
function insert(table, data) {
  return new Promise((resolve, reject) => {
    connection.query(
      "INSERT INTO " + table + " SET ?",
      data,
      function (error, results, fields) {
        if (error) reject(error);
        resolve(results);
      }
    );
  });
}

module.exports = {
  insert,
};
复制代码

调用方法:

const res = await insert('books',getBooks);// getBooks是处理后的json对象
console.log(res.insertId) // 返回插入成功后的自增ID
复制代码

存储JSON

为了便于讲解,我们找一个时间案例,3分钟爬取100部院长喜欢的豆瓣电影,并存为json格式数据。PS:小心极易封IP。 地址拿来:选电影 (douban.com) tag为热门,limit为20

image.png
从url中抓取信息

image.png

image.png

const fs = require('fs')
const cheerio = require('cheerio')
const fetch = require('node-fetch')

function generateUrl(tag, sort, limit, offset) {
  return `https://movie.douban.com/j/search_subjects?type=movie&tag=${encodeURI(
    tag
  )}&sort=${sort}&page_limit=${limit}&page_start=${offset}`
}
const data = []
;(async function () {
  // 5页20个,共100部电影
  for (let i = 0; i < 5; i++) {
    const res = await fetch(
      generateUrl('热门', 'recommend', 20, 0 + 20 * i)
    ).then(res => res.json())
    const list = res.subjects
    list.forEach(async item => {
      const d = {
        title: item.title,
        id: item.id,
        rate: item.rate,
        cover: item.cover
      }
      const url = item.url
      const html = await fetch(url).then(res => res.text())
      const $ = cheerio.load(html)
      const director = $('#info .attrs').eq(0).find('a').text()
      const screenWriters = $('#info span .attrs')
        .eq(1)
        .find('a')
        .map((i, item) => {
          return $(item).text()
        })
        .get()
      const actors = $('#info span .attrs')
        .eq(2)
        .find('span a')
        .map((i, item) => {
          return $(item).text()
        })
        .get()
      const type = $('.pl')
        .eq(3)
        .nextAll("span[property='v:genre']")
        .map((i, item) => {
          return $(item).text()
        })
        .get()
      const date = $('.pl')
        .eq(6)
        .next("span[property='v:initialReleaseDate']")
        .text()
      const duration = $('.pl').eq(7).next("span[property='v:runtime']").text()

      const desc = $("span[property='v:summary']").text()
      const celebrities = $('.celebrities-list .celebrity')
        .map((i, item) => {
          const obj = $(item)
          return {
            url: obj.find('a').attr('href'),
            avatar: obj.find('a .avatar').css('background-image'),
            name: obj.find('.info .name a').text(),
            role: obj.find('.info .role').text()
          }
        })
        .get()
      d.url = url
      d.director = director
      d.screenWriters = screenWriters
      d.actors = actors
      d.type = type
      d.date = date
      d.duration = duration
      d.desc = desc
      d.celebrities = celebrities
      data.push(d)
    })
  }

  fs.writeFileSync('./data.json', JSON.stringify(data, null, 3))
})()

复制代码

image.png 整体没有什么复杂度,新版node支持fetch,实际上只用了一个依赖。由此可以学习到,我们看到的很多电影网站都是通过爬虫相互链接公用资源的。
另外再提供一个,自动登录微博获取cookie,爬取时事要闻的案例,仅供大家学习。微博要闻Github仓库 。还提供了 动态地址API

image.png

总结

本节我们学习了如何快速连接数据库,如果你嫌安装麻烦可以选择免费在线数据库。如果想要保存本地可以选择json格式。
有人私信我为什么会用JS而不是Python?其实,我比较擅长和喜欢使用Python的,只是对于多数的前端开发者学习Python需要一定的门槛,而无论哪一种语言,贵在灵活运用解决问题。对前端同学来说,能够更多的了解NodeJS是个不错的选择。

下节课,我们研究PushMsg工具,并动手封装一个PushMsg插件。

如果喜欢我的文章,麻烦点个赞评个论收个藏关个注

手绘图,手打字,纯原创,摘自未发布的书籍:《高阶前端指北》,转载请获得本人同意。

image.png

猜你喜欢

转载自juejin.im/post/7133106847707299854