MongoDB
非关系型数据库
模式
schemas用于描述数据表
模型
models由schemas发布生成的模型,有增删改查的行为方法
实例
collect帮助表进行读写操作
创建
//安装mongoosenpm i -S mongoose@5.4.21
//基于koa服务端框架编写://1.创建并进入目录src > dbs//2.创建配置文件 config.js//3.配置数据库module.exports = {//协议:端口/数据库名称dbtest: 'mongodb://127.0.0.1:27017/dbtest'}//4.创建dbs > models目录//5.创建文件person.js//6.引入mongooseconst mongoose = require('mongoose');//7.创建schema模式let personSchema = new mongoose.Schema({name: String,age: Number});//8.定义并导出模型module.exports = mongoose.model('Person', personSchema);//9.连接数据库 src > app.jsconst mongoose = require('mongoose');const dbConfig = require('./dbs/config');mongoose.connect(dbConfig.dbtest, {useNewUrlParser: true});
操作
对数据库进行增删改查操作
//编写增加接口//1.路由文件routes > users.js 引入模型const Person = require('../dbs/models/person');//2.新增路由路径 并实例化模型 将数据保存到数据库里//注意:操作数据库都是异步操作router.post('/addPerson', async function (ctx, next) {const person = new Person({name: ctx.request.body.name,age: ctx.request.body.age});await person.save();//返回终端显示 code = 0ctx.body = {code: 0}});//3.postman尝试发送post请求 "name=xiaowang&age=18"//服务器成功返回{"code": 0}//4.打开compass查看dbtest数据库person模型里成功存储post提交的数据信息
//编写查询接口//1.新增路由路径 通过模型查询router.post('/getPerson', async function (ctx, next) {const res = await Person.findOne({name: ctx.request.body.name,});//返回终端显示 code = 0 和 查询结果ctx.body = {code: 0,res}});//2.postman尝试发送post请求 "name=xiaowang"//服务器成功返回{"code": 0} 和 查询到的结果
//编写更改接口//1.新增路由路径 通过模型更改router.post('/updatePerson', async function (ctx, next) {const res = await Person.where({name: ctx.request.body.name,}).update({age: ctx.request.body.age});//返回终端显示 code = 0ctx.body = {code: 0}});//2.postman尝试发送post请求 "name=xiaowang&age=20"//服务器成功返回{"code": 0}//3.打开compass刷新person模型显示更新后的数据
//编写删除接口//1.新增路由路径 通过模型更改router.post('/removePerson', async function (ctx, next) {const res = await Person.where({name: ctx.request.body.name,}).remove();//返回终端显示 code = 0ctx.body = {code: 0}});//2.postman尝试发送post请求 "name=xiaowang"//服务器成功返回{"code": 0}//3.打开compass刷新person模型显示删除后的数据
NuxtJS
概念
前后端分离概念:
前端:
- 写页面和业务脚本
中间层(后端
node):- 拿到数据
- 登录/注册
redis存储- 验证
- 组件
html - 返回完整的
html静态页面 - 向后端请求数据
后端:
- 写数据接口
- 数据库对接
- 数据返回
问题:Nuxt做了什么?
vue组件集合Nuxt页面打包Nuxt请求数据- 组件与数据结合
- 组件
html
基于vuejs通用应用框架
关注于UI应用渲染,对客户端服务端基础架构的组织实现的,还预设了vuejs开发渲染应用所需要的各种配置
安装
SSR + Nuxtjs
//创建Nuxtjs项目脚手架npx create-nuxt-app@2 my-first-nuxt-app
什么是服务端渲染?
路由
在Nuxt的路由机制是一个.vue组件文件就一个子路由,主要根据pages目录的文件嵌套关系来确定路由的嵌套关系
pages目录直接定义组件,不用配置路由文件即可创建路由路径/about
//nuxt脚手架根目录下pages目录下新建about.vue<template><div>这是关于页面</div></template>
布局
布局模板layouts
//根目录下layouts目录下的模板可以被其他组件指定并继承该模板的布局和样式//如pages > aaa.vue<template>...</template><script>export default{//这里可以指定layouts目录下的模板名称layout: 'bbb'}</script>
标签
<nuxt />
该标签占位在根组件,实际是子组件的文本内容
<nuxt-link>
该标签是跳转元素标签,相当于a标签
<nuxt-link to="/changeCity"></nuxt-link>
接口
编写后台接口
//server目录新建dbs数据库目录//dbs数据库目录里创建models模型目录//server > dbs > models模型目录创建users.js文件//server > dbs目录下创建config.js配置文件(数据库相关信息)//server目录新建interface接口目录//interface目录新建utils工具目录//server > interface新建users.js文件//server > interface > utils新建axios.js文件(封装全局使用axios)//server > interface > utils新建passport.js文件(验证相关权限)
案例
案例:JS++官网移动版
这是一个基于服务端渲染,数据来源于爬虫制作课堂官网的移动版
技术:
NuxtJSvuex(内置)
功能:
- 首页
列表页
tab栏点击会切换页面tab栏点击会与屏幕左侧贴齐
- 错误页
- 移动端和网页端适配时切换
案例图片:


启动:
npm run dev
接口:
- 请求首页数据:
/api/get_home_data - 请求列表页数据:
/api/get_list_data - 请求列表页课堂数据:
/api/get_course_data
源码目录:
├─.editorconfig├─.gitignore├─nuxt.config.js - nuxt服务器配置文件/插件/样式加载/头部信息├─app.html - nuxt提供的模板/移动端网页端适配/乱码BUG修复├─package-lock.json├─package.json├─README.md├─utils| ├─http.js - 封装axios请求| └tools.js - 工具方法/切换tab定位/课堂数据过滤├─store| ├─index.js - store仓库/容器/方法├─static - 不被打包的静态目录| ├─favicon.ico├─server - 后端服务器| ├─index.js| ├─services| | ├─Collection.js| | ├─Course.js| | ├─CourseTab.js| | ├─RecomCourse.js| | ├─Slider.js| | ├─Student.js| | └Teacher.js| ├─routes| | └index.js| ├─libs| | └utils.js| ├─db| | ├─db_connect.js| | ├─models| | | ├─aboutus.js| | | ├─agencyInfo.js| | | ├─collection.js| | | ├─course.js| | | ├─courseTab.js| | | ├─recomCourse.js| | | ├─slider.js| | | ├─student.js| | | └teacher.js| ├─controllers| | └Home.js| ├─configs| | ├─db.js| | ├─db_type.js| | ├─env.js| | ├─link.js| | ├─manual.js| | ├─nav.js| | ├─page.js| | ├─qiniu.js| | ├─qr.js| | └url.js├─plugins - 存放前端使用的插件文件(生产依赖文件)| ├─vue-awesome-swiper.js| └vue-lazyload.js├─pages - 视图绑定/前后端数据请求/下拉功能实现| ├─index.vue - 首页| ├─list.vue - 列表页├─middleware├─layouts| ├─default.vue| └README.md├─config| └config.js├─components| ├─list| | ├─listTab| | | ├─index.vue| | | └tabItem.vue| ├─index| | ├─teacher| | | ├─index.vue| | | └teacherItem.vue| | ├─swiper| | | ├─index.vue| | | └swiperItem.vue| | ├─recomCourse| | | ├─courseItem.vue| | | └index.vue| | ├─courseNav| | | ├─index.vue| | | └navItem.vue| | ├─cooperation| | | ├─cooperationItem.vue| | | └index.vue| | ├─collection| | | ├─collectionItem.vue| | | └index.vue| ├─common| | ├─scrollWrapper| | | └index.vue| | ├─pullingDownLoading| | | └index.vue| | ├─mainTitle| | | └index.vue| | ├─header| | | ├─BackIcon.vue| | | ├─index.vue| | | ├─ListIcon.vue| | | └Logo.vue| | ├─footer| | | └index.vue| | ├─error| | | └index.vue| | ├─course| | | ├─courseItem.vue| | | └index.vue├─assets - 被打包的资源文件目录| ├─styles| ├─scripts| ├─images
源码地址: https://gitee.com/kevinleeeee/crawler-txcourse-mobile-nuxt-demo
Redis
NoSql非关系型数据库(not-only sql)
概念
Redis——C语言开发——键值存储数据库——处理大量数据的高访问负载
优势:快速查询
劣势:存储的数据缺少结构化
Redis的庞大用户群体:新浪微博、知乎网、GitHub、Stack,Overflow等。
区别:
Redis:内存数据库- 访问快/内存压力大/缓存公共数据和登录信息
MySQL:硬盘数据库- 访问较慢/内存压力小/静态数据集合/非公共数据/网站的视图数据
应用场景1:
high performance:对数据库高并发读写huge storage:对海量数据的高效率存储和访问high scalability&&high availability:对数据库的高可扩展性和高可用性
应用场景2:
缓存(数据查询、新闻内容、商品内容)、分布式集群架构中的session分离、任务队列、数据过期处理等。
无状态
用户状态存储管理,记录用户访问的记录
HTTP是无状态的,利用服务器session存储信息
安装
//全局安装redis//github下载地址://https://github.com/microsoftarchive/redis/releases/tag/win-3.2.100//安装后cmd找到目录打开redisC:\Program Files\Redis>redis-server redis.windows.con//项目安装依赖npm i -S redis@3.0.2
启动
//暂停redisredis-server --service-stop//启动redisredis-server --service-start//or.\redis-server//另一个终端启动客户端.\redis-cli
使用
//操作redis//设置set name 'xxx'//获取get name//获取redis所有keykeys *//删除keydel name//退出客户端exit
koa2配置redis:
//安装koa-redis和koa-generic-sessionnpm i -S koa-redis@4.0.1npm i -S koa-generic-session@2.0.4
//基于koa服务端框架编写://app.js引入const Redis = require('koa-redis');const session = require('koa-generic-session');//对session进行加密app.keys = ['some secret hurr'];//使用中间件 连接redisapp.use(session({store: new Redis()}))
//编写测试的中间件//src > middleware > koa-mid.jsfunction mid(ctx) {//打印页面路径console.log('midtest', ctx.path);ctx.session.count++;}module.exports = function () {return async function (ctx, next) {mid(ctx);await next();}}//回到浏览器访问http://localhost:3000///在Application里cookies存储新的sid字段保存key/value//koa.sid.sig:p5lZOKL2rOIEEkLjl8QEnVabvBU//koa.sid:u15MkW5tT2KfIXCOZ_jofaqJVde6KtWT//说明用户下次访问时一直拿到该session的值来区分哪个用户进行访问
//自定义session键名称app.use(session({key: 'test',prefix: 'testprefix'store: new Redis()}))//回到浏览器访问http://localhost:3000///在Application里cookies存储新的sid字段保存test名字的key
关于session存储到redis:
session数据量小session不考虑数据丢失问题session访问度高,要求访问快,性能高
问题:什么情况不适合redis?
- 操作频率不高的数据
- 数据无法承受丢失的结果
- 数据量大,内存无法承受
项目中配置redis:
//1.安装依赖npm i -S koa-redis@4.0.1npm i -S koa-generic-session@2.0.4(操作session和redis用)//2.引入const redis = require('redis');//3.创建redis客户端const red = redis.createClient(['6379', '127.0.0.1']);//4.监听错误red.on('error', (error) => {console.error('Redis error: ' + error);});//5.设置键名和超时function redisSet(key, value, timeout = 60 * 60) {if (typeof (value) === 'object') {value = JSON.stringify(value);}red.set(key, value);red.expire(key, timeout);}//6.获取键名的值function redisGet(key) {return new Promise((resolve, reject) => {red.get(key, (error, value) => {//错误时if (error) {reject(error);return;}//值为空时if (value == null) {resolve(null);return;}//JSON字符串时//尝试,忽略错误try {resolve(JSON.parse(value));} catch (e) {resolve(value);}})});}
Puppeteer
nodejs提供的一个库,实现爬虫页面程序,它提供一个高级API来通过DevTools协议来控制chrome
它还能做:
- 生成页面的屏幕截图和 PDF
- 抓取 SPA(单页应用程序)并生成预渲染内容(即“SSR”(服务器端渲染))
- 自动化表单提交、UI 测试、键盘输入等
- 创建最新的自动化测试环境。使用最新的 JavaScript 和浏览器功能直接在最新版本的 Chrome 中运行测试
- 捕获您网站的时间线轨迹以帮助诊断性能问题
- 测试 Chrome 扩展程序
搭建
koa2环境
//1.创建项目:koa2 + 项目名称koa2 crawler-puppeteer-txcourse-demo//2.安装依赖npm install//3.安装爬虫库 Puppeteernpm i -S puppeteer@2.1.1
编写
编写爬虫程序
//4.在routes目录下的index.js里//4.1 引入爬虫依赖const pt = require('puppeteer');//4.2 在请求响应路由程序里编写爬虫程序router.get('/', async (ctx, next) => {//爬虫程序编写区域...});//4.3 发起启动爬虫程序const broswer = await pt.launch();//4.4 配置爬取页面const url = 'https://msiwei.ke.qq.com/',//4.5 在浏览器里启动新的标签页const pg = await broswer.newPage();//4.6 等待新页面打开url地址//第二参数为配置项await pg.goto(url, {//超时timeout: 30 * 1000,//直到完成 networkidle2官方推荐(一定时间内没有发送请求证明爬取完成)waitUntil: 'networkidle2'});//4.7 分析页面后返回结果const result = await pg.evaluate(() => {//定义数据的容器(接收爬取后的数据)let data = [];//分析爬取内容...//把内容存到容器里//返回爬取的容器return data;}//5.爬取数据后关闭浏览器await broswer.close();
查看
查看爬取结果
//1.启动项目npm run dev//2.访问localhost:3000//3.等待爬取//4.爬取完毕,终端打印爬取后的数组数据[{...},{...},{...}]
子进程
开启子进程开启爬虫程序,建立单独的文件管理子进程pupeteer目录下的crawler.js自己执行的脚本,存放爬虫程序
//1.拆分请求路由下爬虫程序到子进程文件中//2.路由文件引入子进程库const cp = require('child_process');//3.读取子进程脚本文件router.get('/', async (ctx, next) => {const script = resolve(__dirname, '../puppeteer/crawler.js')//4.启动子进程const child = cp.fork(script, []);//5.完善成功/退出/失败时程序日志child.on('message', (data) => {...});child.on('exit', (code) => {...});child.on('error', (err) => {...});});
案例
案例:爬虫系统
实现一个专门爬虫程序脚本的系统,如爬取腾讯课堂官网,一个课程管理后台的API后端
功能:
- 主进程管理
- 子进程管理
- 多个不同目标网页的爬虫程序抽离
- 将爬虫后的图片上传至七牛服务器
- 数据库
MySQL上传 - 访问服务器需要携带
cookie(实现登录无状态访问) - 账号管理数据库
技术:
koa2puppeteer:爬虫库nanoid:随机生成idqiniu:七牛库sequelize:可以操作许多数据库的程序(如MySQL)- 可以建表(
authenticate()/define()/sync()) - 增删改查
- 避免取手动直接操作数据库
- 避免使用
SQL语句 - 对象的方式模拟操作数据表
- 需要依赖
mysql2 - 数据入表
- 可以建表(
redis:保存用户数据信息session:保存用户数据信息crypto:密码明文加密koa2-cors:解决客服端请求跨域
项目启动:
启动后端:
npm run dev- 开启服务
phpStudy里的MySQL和Apache - 访问数据库网页(删除所有表)
- 同步所有数据表(重置新增表)
- 访问七牛空间(清空图片存储)
启动前端后台项目(重新爬取数据)
npm start
- 启动前端前台项目
爬取接口:
- 首页轮播图:http://localhost:3000/crawler/crawl_slider_data
- 首页标题栏数据:http://localhost:3000/crawler/crawl_agency_info
- 首页推荐列表数据(重点合辑):http://localhost:3000/crawler/crawl_recom_course
- 首页列表数据(合辑推荐):http://localhost:3000/crawler/crawl_collection
- 老师页老师列表:http://localhost:3000/crawler/crawl_teacher
- 首页优秀学员列表:http://localhost:3000/crawler/crawl_student
- 课程页选项卡数据列表:http://localhost:3000/crawler/crawl_course_tab
- 课程页课程列表数据:http://localhost:3000/crawler/crawl_course_data
- 关于页数据:http://localhost:3000/crawler/crawl_aboutus
API接口:
get请求:- 根路径:http://localhost:3000/
- 创建管理员:http://localhost:3000/admin/create_admin
- 登录验证状态接口(默认组件加载完时发送请求, 只携带
cookies信息):http://localhost:3000/admin/login_check - 登出接口:http://localhost:3000/admin/logout_action
- 请求课堂列表和选项卡数据:http://localhost:3000/get_course_data
- 请求课堂推荐列表数据:http://localhost:3000/get_recom_course_data
- 请求轮播图数据:http://localhost:3000/get_sliders
- 请求课程集合数据:http://localhost:3000/get_collections
- 请求老师数据:http://localhost:3000/get_teachers
- 请求学生数据:http://localhost:3000/get_teachers
post请求:
redis终端操作:
- 找到
redis目录:C:\Program Files\Redis - 终端1:开启服务
.\redis-server 终端2:进入服务器
.\redis-cli- 查询
keys * - 获取
get 'xxx' - 设置
set name 'xxx'
- 查询
数据库创建步骤:
- 定义入口文件导入数据库配置信息
- 创建一个数据库(
new Sequelize(数据库名称, MySQL用户名密码, 配置项)) - 定义各种表模型(
new Sequelize().define(表名称, 配置字段对象)) - 执行同步(
new Sequelize().sync())将表导入数据库 - 定义数据项
- 对数据项进行增删改查(
new TeacherService()) - 数据入库(
addTeacher(data))
数据库管理:
数据库命令操作:
- 执行同步程序来建表:
node db/sync.js
图床服务器管理:
项目目录:
├─app.js - 服务器/路由中间件/使用session├─package.json├─db - 数据库目录| ├─sync.js - 同步程序运行模型表的文件| ├─models - 模型表| | ├─aboutus.js - 描述aboutus的表| | ├─teacher.js - 描述teacher的表| | ├─student.js - 描述student的表| | ├─Course.js - 描述course的表| | ├─CourseTab.js - 描述course_tab的表| | ├─collection.js - 描述collection的表| | ├─recomCourse.js - 描述recom_course的表| | ├─agencyInfo.js - 描述agency_info的表| | ├─index.js - 出口文件| | └slider.js - 描述slider的表| ├─connections - 创建数据库的入口文件| | ├─redis_connect.js - 创建redis客户端程序| | └mysql_connect.js - 实例化创建数据程序├─routes| ├─admin.js - 理由请求/admin/create_admin 执行控制器| ├─crawler.js - 路由请求路径/crawler 执行控制器| └index.js - 路由请求路径/ 执行控制器├─middlewares - 中间件| └loginCheck.js - 处理是否登录/判断是否带有cookie/session信息├─libs| ├─crawler.js - 封装一个爬虫主进程程序| ├─redisClient.js - 封装redis里的set/get方法| └utils.js - 子进程工具/管理进程状态日志/爬虫工具/上传工具/加密├─crawlers - 爬取DOM的jQuery逻辑代码(爬虫文件)| ├─aboutus.js - 关于页数据| ├─teacher.js - 首页老师列表| ├─student.js - 首页学生列表| ├─course.js - 课堂页课堂列表| ├─courseTab.js - 课堂页课堂tab列表| ├─collection.js - 首页列表数据(合辑推荐)| ├─recomCourse.js - 首页推荐列表| ├─agencyInfo.js - 首页标题栏| └slider.js - 首页轮播图├─controllers - 专门控制器文件处理爬虫程序| ├─Admin.js - 实例化访问管理路径新建管理员账户/密码加密| ├─Index.js - 实例化访问根路径服务器响应相应内容| ├─Crawler - 实例化爬虫数据的方法集合类| | ├─aboutus.js| | ├─agencyInfo.js| | ├─collection.js| | ├─course.js| | ├─courseTab.js| | ├─index.js - 出口文件/新增上传七牛方法/数据入数据库方法| | ├─recomCourse.js| | ├─sliderData.js| | ├─student.js| | └teacher.js├─services - 服务目录/每一个表对应着每一个服务/实例化一个新的服务| ├─Aboutus.js - 对数据库里的aboutus表进行更改| ├─Teacher.js - 对数据库里的teacher表进行更改| ├─Student.js - 对数据库里的student表进行更改| ├─Course.js - 对数据库里的course表进行更改| ├─CourseTab.js - 对数据库里的courseTab表进行更改| ├─Collection.js - 对数据库里的collection表进行更改| ├─RecomCourse.js - 对数据库里的recomCourse表进行更改| ├─AgencyInfo.js - 对数据库里的agencyInfo表进行更改| └Slider.js - 对数据库里的slider表进行更改├─config| ├─config.js - 七牛账号/爬虫页面/session&cookie&redis信息配置/管理员账户/密钥| ├─db_config.js - 数据库/redis配置文件| ├─db_type_config.js - 定义数据库类型的配置文件| ├─env_config.js - 定义环境变量的配置文件| └error_config.js - 定义成功或错误的状态码信息配置文件├─views - 视图模板| └index.ejs - 根路径视图html├─bin - koa2服务器主程序| └www
源码地址(非开源):
