携手创作,共同成长!这是我参与「掘金日新计划 · 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
从url中抓取信息
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))
})()
复制代码
整体没有什么复杂度,新版node支持fetch,实际上只用了一个依赖。由此可以学习到,我们看到的很多电影网站都是通过爬虫相互链接公用资源的。
另外再提供一个,自动登录微博获取cookie
,爬取时事要闻的案例,仅供大家学习。微博要闻Github仓库 。还提供了 动态地址API
总结
本节我们学习了如何快速连接数据库,如果你嫌安装麻烦可以选择免费在线数据库。如果想要保存本地可以选择json格式。
有人私信我为什么会用JS而不是Python?其实,我比较擅长和喜欢使用Python的,只是对于多数的前端开发者学习Python需要一定的门槛,而无论哪一种语言,贵在灵活运用解决问题。对前端同学来说,能够更多的了解NodeJS是个不错的选择。
下节课,我们研究PushMsg工具,并动手封装一个PushMsg插件。
如果喜欢我的文章,麻烦点个赞,评个论,收个藏,关个注。
手绘图,手打字,纯原创,摘自未发布的书籍:《高阶前端指北》,转载请获得本人同意。