dbmovie记录

流程

  1. 抓取数据
  2. 数据入库
  3. 启动服务
  4. 渲染数据

依赖

1
2
3
4
5
6
7
8
9
10
"dependencies": {
"bluebird": "^3.5.5", // 这个项目中将数据库的query方法promisify
"cheerio": "^1.0.0-rc.3", // 像jquery一样操作
"debug": "^4.1.1", // cmd可以打印相关信息,简洁明了
"ejs": "^2.7.1", // 前端渲染页面
"express": "^4.17.1", // 开启后端服务器
"mysql": "^2.17.1", // 使用mysql数据库
"request": "^2.88.0", // 进行html爬取
"request-promise": "^4.2.4" // request的小弟
}

爬取导入库

read.js进行读取操作

  • 通过request抓取了html代码
  • cheerio将html转成了dom
  • 将需要的内容存在数组(名称|评分|地址|图片|id)
  • 返回结果数组并导出read方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
const rp = require('request-promise');
const cheerio = require('cheerio');
const debug = require('debug')('movie:read');
const read = async (url) => {
debug('开始读取最近上映的电影');

const opts = {
url,
transform: body => {
return cheerio.load(body);
}
};

return rp(opts).then($ => {
let result = []; // 结果数组

$('#screening li.ui-slide-item').each((index, item) => {
// ...
});
return result;
});
};

module.exports = read;

db.js 连接数据库,导出promisify query 方法

write.js 将数据写入数据库

index.js为入口函数

1
2
3
4
5
6
7
8
9
10
11
(async () => {
// 异步抓取目标页面
const movies = await read(url); // 这里要用await,因为read()函数是async式的,返回的是promise,如下
// const movies = read(url);
// console.log(movies); Promise { <pending> }

// 写入数据到数据库
await write(movies); // 这里也要添加await关键字,等到写完再关闭程序
// 完毕后退出程序
process.exit();
})();

前端展示

使用 ejs 模板,查询到数据后渲染到 index.html 页面。

1
2
3
4
5
6
7
8
9
// 首页路由
app.get('/', async (req, res) => {
// 通过SQL查询语句拿到库里的movies表数据
const movies = await query('SELECT * FROM movies');
// 渲染首页模板并把movies数据传过去
res.render('index', {
movies
});
});

DEBUG

https://www.npmjs.com/package/debug

1
set DEBUG=movie:* # debug模块需要先设置

项目启动

在 README.md 里

bug

注意这个项目中 async 和 await 的使用,个人觉得非常巧妙,还有下面的 promisify,值得好好学习。

mysql 的 query 方法 promisify 后进行 bind 绑定,以免 this 混乱。

https://stackoverflow.com/questions/44004418/node-js-async-await-using-with-mysql/51690276#51690276

参考

https://juejin.im/post/5ac9bc56f265da238c3af18f#heading-11