note: demo代码要编号

导出模块

一个js文件就是一个模块,模块内部的所有变量,对象,方法对外界都不可见。如果想暴漏出去让别人用,就需要导出模块。语法如下:

module.exports = {
a :a,
foo
}

crypto模块

NodeJs的crypto模块提供了哈希,加密相关的功能支持。

哈希算法:MD5,SHA1,SHA256,Hmac

哈希算法用来对数据进行签名,确定数据的唯一性,以及是否被篡改。由于其过程不可逆,也常常用来对用户密码进行加密。

// 计算字符串的hash
let data = '123456'
// const hash = crypto.createHash('md5')
// const hash = crypto.createHash('sha1')
// const hash = crypto.createHash('sha256')
const hash = crypto.createHash('sha512')
hash.update(data)
console.log(hash.digest('hex'));
// 计算文件的hash
const reader = fs.createReadStream('xxx.txt')
reader.on('data', (chunk) =>{
hash.update(chunk)
})
reader.on('end', ()=>{
console.log(hash.digest('hex'));
})

Hmac是基于key和hash的认证算法。它在上面哈希算法的基础上,再传入一个key。只要key变化,即使输入同样的数据也会得到不同的结果。可以将Hmac理解为随机数增强的哈希算法。

const key = 'hehe'
const hmac = crypto.createHmac('md5', key)
hmac.update(data)
console.log(hmac.digest('hex'));

对称加密算法:AES

AES是一种常用的对称加密算法,加解密都用同一个密钥。

AES加密:

let data = '123456'
let password = 'baby'
const cipher = crypto.createCipher('aes192', password)
let encrypted = cipher.update(data, 'utf-8', 'hex')
encrypted += cipher.final('hex')
console.log(encrypted);

AES解密:

const decipher = crypto.createDecipher('aes192', password)
let encrytedData = 'd1b992fe45e85e43f3b73e0716874bc8'
let decrypted = decipher.update(encrytedData, 'hex', 'utf-8')
decrypted += decipher.final('utf-8')
console.log(decrypted);

event模块

大多数 Node.js 核心 API 都采用惯用的异步事件驱动架构,其中某些类型的对象(触发器)会周期性地触发命名事件来调用函数对象(监听器)。例如,fs.ReadStream会在文件被打开时触发事件;stream 会在数据可读时触发事件。

用法如下:

const EventEmitter = require('events')
class MyEmitter extends EventEmitter{} const myEmitter = new MyEmitter()
// 注册xxx事件
myEmitter.on('aaa', (a)=>{
console.log('aaa事件被触发,参数:'+a);
})
// 1秒钟之后触发aaa事件,并传递参数
setTimeout(()=>{
myEmitter.emit('aaa', 'aaaaaa')
},1000)

当你想设计一个模块,它具有在某个条件下执行某个操作的功能,那么event模块就派上用场了。例如:你想设计一个用户注册模块,当用户注册成功之后给用户发送一个email。

【案例】美女图片爬虫项目

功能需求:爬取http://www.27270.com/ent/meinvtupian/网站页面,处理GBK乱码的问题;从中提取出图片数据,并下载美女图片。

提示:html的解析需要用到cheerio模块,使用iconv-lite模块处理gbk编码问题,iconv-lite Github

前置知识点学习:

  • 学习使用cheerio模块进行数据的提取。cheerio官方文档

    参考官网的api,分别练习从一段给定的dom中,提取标签的text,属性值,以及如何取多个标签的text。

实现爬虫功能,需要实现抓取页面,提取数据,下载图片,这些子功能。而这些功能的调用都是当某个步骤完成了,就执行下一个步骤,有顺序的。

所以,请尝试使用event模块来重构整个项目的架构


MongoDB

介绍

MongoDB是一个由C++编写的高性能的文档型数据库,为web应用提供可扩展数据库解决方案。它和MySQL的区别如下:

项目 MongoDB MySQL
存储单元 按collection存储,一个collection中包含很多document 按table存储,一个table中包含很多的记录
数据格式要求 非常灵活,document可以存储任意json格式的数据 row中的每一列的数据类型都是限定死的,不够灵活
数据字段扩展 对数据字段的扩展零消耗 数据扩展字段有很大的消耗。比如:上万条数据再增加一列就要消耗几十秒。
事务支持 在4.0之后版本支持,目前已经支持 支持
读写性能 一般情况下,读写性能都要略高于MySQL 性能平稳

具体区别如下:

下载与安装

下载地址:https://www.mongodb.com/download-center?jmp=nav#community,然后傻瓜式安装。

启动

  • 为了方便执行命令,先将安装目录下的bin添加到环境变量中。

  • 启动server端:mongod --dbpath F:\xxx

  • 启动clent端:mongo

  • 为了方便,推荐将mongodb设置为Windows的开机启动服务,做法如下:

    1. 在mongodb的根目录下创建mongo.config文件,内容如下:

      dbpath=F:\mongodb\data
      logpath=F:\mongodb\log\mongo.log
    2. 用管理员启动cmd,执行:

      mongod --config f:\mongodb\mongo.config --install --serviceName mongodb

      服务安装完毕,不要忘记启动服务。

    3. 启动和停止服务

      net start/stop mongodb

mongo shell的增删改查

简单演示。


ORM - mongoose

无论是mysql还是mongodb,传统的与数据库交互的方式都是按照他们提供的API来写代码。它们提供的API往往不是很容易理解,而且难以记忆,如果传错了参数,写错一个符号都要查文档。就像上面我们学习的数据库API一样。

ORM框架允许我们面向对象操作,不需要记忆任何的数据库API,只需要操作对象即可,由框架底层去调用数据库API,这样就大大提高了程序员的开发效率。不过既然多了一层封装,肯定要损失一点点的性能,可以忽略不计。

在NodeJS中,mongodb最好的orm框架就是mongoose

安装mongoose

npm install mongoose --save

如果你本机没有安装nodejs驱动,会自动安装nodejs驱动,因为mongoose依赖nodejs驱动了。

文档参考:mongoose官方文档

连接数据库

const mongoose = require('mongoose')
//连接数据库
mongoose.connect("mongodb://127.0.0.1:27017/test");
const db = mongoose.connection; db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function() {
console.log('连接mongodb成功!');
});

模型定义

mongoose使用schema来描述数据的格式,字段,规则,有了schema之后可以生成model来操作数据。

const mongoose = require('mongoose')
const schema = mongoose.Schema({
name: {
type: String,
required: true
},
age: Number,
fav: [String],
}); module.exports = mongoose.model('user', schema)

增删改查

直接查看文档中Model相关API。

await User.create()
await User.findOne()
await User.updateOne()
await User.deleteOne()
//增加条件操作符: 所有支持的操作符:https://docs.mongodb.com/manual/reference/operator/query/
await User.findOne({
age: {$gt:11},
tags:{$in:[1,2,3]}
})

高级查询

//分页查询
await Book.find().skip(10).limit(10) //排序和字段映射
await Book.find().sort("field").select("field1 field2") // 填充查询
let res = await Book.find({price: {$gt: 50}}).populate('author', 'name')
console.log(res);

NodeJs02 美女爬虫的更多相关文章

  1. 百度搜索引擎关键字URL采集爬虫优化行业定投方案高效获得行业流量-代码篇

    需要结合:<百度搜索引擎关键字URL采集爬虫优化行业定投方案高效获得行业流量--笔记篇> 一起看. #!/user/bin/env python # -*- coding:utf-8 -* ...

  2. Python爬虫学习之爬美女图片

    最近看机器学习挺火的,然后,想要借助业余时间,来学习Python,希望能为来年找一份比较好的工作. 首先,学习得要有动力,动力,从哪里来呢?肯定是从日常需求之中来.我学Python看网上介绍.能通过P ...

  3. Python爬虫下载美女图片(不同网站不同方法)

    声明:以下代码,Python版本3.6完美运行 一.思路介绍 不同的图片网站设有不同的反爬虫机制,根据具体网站采取对应的方法 1. 浏览器浏览分析地址变化规律 2. Python测试类获取网页内容,从 ...

  4. Scrapy爬取美女图片第四集 突破反爬虫(上)

     本周又和大家见面了,首先说一下我最近正在做和将要做的一些事情.(我的新书<Python爬虫开发与项目实战>出版了,大家可以看一下样章) 技术方面的事情:本次端午假期没有休息,正在使用fl ...

  5. 使用Python爬虫爬取网络美女图片

    代码地址如下:http://www.demodashi.com/demo/13500.html 准备工作 安装python3.6 略 安装requests库(用于请求静态页面) pip install ...

  6. 【Python3爬虫】爬取美女图新姿势--Redis分布式爬虫初体验

    一.写在前面 之前写的爬虫都是单机爬虫,还没有尝试过分布式爬虫,这次就是一个分布式爬虫的初体验.所谓分布式爬虫,就是要用多台电脑同时爬取数据,相比于单机爬虫,分布式爬虫的爬取速度更快,也能更好地应对I ...

  7. Python爬虫实战 批量下载高清美女图片

    彼岸图网站里有大量的高清图片素材和壁纸,并且可以免费下载,读者也可以根据自己需要爬取其他类型图片,方法是类似的,本文通过python爬虫批量下载网站里的高清美女图片,熟悉python写爬虫的基本方法: ...

  8. Python爬虫 —— 抓取美女图片(Scrapy篇)

    杂谈: 之前用requests模块爬取了美女图片,今天用scrapy框架实现了一遍. (图片尺度确实大了点,但老衲早已无恋红尘,权当观赏哈哈哈) Item: # -*- coding: utf-8 - ...

  9. 自学Python十 爬虫实战三(美女福利续)

    我又来送福利啦!!!不同于上篇文章,这次我们的爬虫采用了多线程,一直以来被所谓的分布式  多线程  爬虫 给唬的怕怕的.今天就来一发多线程爬虫吧,还能看妹子图,想想就觉得很激动!!! 依然是流程解释: ...

随机推荐

  1. 会话技术: Cookie Session JSP

    ##  Cookie A..概念:客户端会话技术,将数据保存到客户端 B.使用步骤: 1.创建Cookie对象,绑定数据 new Cookie(String  name, String value) ...

  2. 20145238-荆玉茗 《Java程序设计》第7周学习总结

    20145238 <Java程序设计>第7周学习总结 教材学习内容总结 第13章时间与日期 13.1.1 ·即使标注为GMT(格林威治时间),实际上谈到的的是UTC(Unix时间)时间. ...

  3. 预处理-04-#if defined和#if !defined

    因为对于一个大程序而言,我们可能要定义很多常量( 不管是放在源文件还是头文件 ),那么我们有时考虑定义某个常量时,我们就必须返回检查原来此常量是否定义,但这样做很麻烦. if defined 宏正是为 ...

  4. Spring Security 之Session管理配置

    废话不多说,直接上代码.示例如下: 1.   新建Maven项目  session 2.   pom.xml <project xmlns="http://maven.apache.o ...

  5. 使用session处理用户搜索后数据的上一页和下一页跳转

    搜索语句界面: /*单一检索:此处为一个下拉列表的检索*/ if(isset($_POST['submit']) && $_POST['submit'] == '点击搜索') { if ...

  6. jquery 标签中的属性操作

    .arrt() 获取匹配的元素集合中的第一个元素的属性值,或设置每一个元素中的一个或多个属性值. .attr(attributeName) $("em").attr("t ...

  7. 洛谷题解:P1209 【[USACO1.3]修理牛棚 Barn Repair】

    原题传送门:https://www.luogu.org/problemnew/show/P1209 首先,这是一道贪心题.  我们先来分析它的贪心策略.  例如,样例:  4 50 18  3 4 6 ...

  8. 【杂题总汇】Codeforces-67A Partial Teacher

    [Codeforces-67A]Partial Teacher 上周刷了一大堆小紫薯的动态规划的题

  9. 【MYSQL笔记2】复制表,在已有表的基础上设置主键,insert和replace

    之前我自己建立好了一个数据库xscj:表xs是已经定义好的 具体的定义数据类型如下: 为了复制表xs,我们新建一个表名为xstext,使用下列语句进行复制xs,或者说是备份都可以: create ta ...

  10. 用MySQL的optimizer_trace进行sql调优

    在我们调优MySQL的SQL时候,通常使用三种工具进行查看sql执行的效率,explain.profile.optimizer_trace.前两个经常被人使用,由于第三个难度较大,大家使用的较少,下面 ...