|
- z, F D. n% N+ |; C' W Koa -- 基于 Node.js 平台的下一代 web 开发框架 ) w4 W \0 B9 I/ n5 j A7 R& T
koa是由 Express 原班人马打造的,致力于成为一个更小、更富有表现力、更健壮的 Web 框架。 使用 koa 编写 web 应用,可以免除重复繁琐的回调函数嵌套, 并极大地提升错误处理的效率。koa 不在内核方法中绑定任何中间件, 它仅仅提供了一个轻量优雅的函数库,使得编写 Web 应用变得得心应手。开发思路和express差不多,最大的特点就是可以避免异步嵌套。koa2利用ES7的async/await特性,极大的解决了我们在做nodejs开发的时候异步给我们带来的烦恼。
' b1 g6 v: x5 ?5 s# n 英文官网:http://koajs.com
3 F) S9 E1 ^# {% i2 t7 d 中文官网:http://koajs.cn 6 f# D( l9 ]; B! s
1.koa
. v p8 j' ? o; f 安装koa包: npm i -S koa@latest 6 P" j( t' \3 l t
引入: const koa = require("koa"); 实例化对象: const app = new koa;
2 s5 F0 V, ^4 B+ `, X/ D2 [( b B 通过实例操作,专门用于客户端请求的函数叫做中间件,使用use()注册
9 X4 j2 w* O/ j0 _3 v5 @ use()函数中必须使用异步 async; use可是调用无数次;
/ _9 g: ~* i- ?6 m, ~1 S6 f 其中有两个参数: ! W5 u" I# q) E l7 R
a)ctx: 上下文环境,node的请求和响应对象,其中不建议使用node原生的req和res属性,使用koa封装的requset和response属性
, F" U2 y+ v* k' d; s/ s$ p- X b)next: next(),将本次控制权交给下一个中间件。 ' c* ~- j( x! L. P9 L0 E
最后一个中间件使用next()无意义,执行完控制权返回上一层,直至第一个。 # Z9 G, W! S7 d q3 G$ R
1. next参数的使用demo ' F$ I h7 h4 R
`const Koa = require(``"koa"``);`+ y( r' F0 ]. d* @
`const koa =` `new` `Koa();`: d$ p1 A1 u+ p- B( d2 y# H
`//中间件1`/ f/ O1 j% t: s
`koa.use(async (ctx, next) => {`
5 _8 s2 K+ g) B" b4 S `console.log(``"1 , 接收请求控制权"``);`
- F- d9 h+ @2 \% _* g `await next();` `//将控制权传给下一个中间件`
: O* Y* E4 S: T; g0 S `console.log(``"1 , 返回请求控制权"``);`
1 z) n$ q% n, @4 U `});` `//将中间件注册到koa的实例上`
O: ]% y+ {) J1 r( q% H$ L& v% O `//中间件2`* C4 B1 t5 I3 A# y* T* e
`koa.use(async (ctx, next) => {`
! _4 H3 ]) f4 w `console.log(``"2 , 接收请求控制权"``);`
I8 j" Y1 w& G, g& B9 |: d6 K& v await next();`
J/ a% Y5 |# y- e `console.log(``"2 , 返回请求控制权"``);`
) E, t3 A8 Y$ A& V9 W, D. t; ~( d `});`
, @' h4 ^6 f7 `4 H `//中间件3`
7 t/ T" H- h) x9 d. @ `koa.use(async (ctx, next) => {`& A/ ^* P0 Y0 I$ R& Z7 D
`console.log(``"3 , 接收请求控制权"``);`
/ o( A7 H( F4 B$ P" g' n. t. R `console.log(``"3 ,返回请求控制权"``);`$ ]) i4 v) e& X6 S1 F
`});`- O& F3 n+ |# B/ O$ |3 f2 E: y5 B3 V
`koa.listen(3000, ()=>{`$ y1 o( x, n6 ^ V0 M
`console.log(``"开始监听3000端口"``);`; N& { f# d% g% X9 u2 @. ^
`});`
9 R$ R. B z3 y4 n0 l; I6 ? 注:当中间件中没有next(),不会执行下面的中间件 1 K) N/ [5 Y- ?
访问localhost:3000的效果图;
/ E, V. {6 e f w- @ : i/ A& u' t, L/ }% l
注:会有两次操作是因为图标icon也会请求一次 1 Z* N1 U, ?/ X7 J
2.ctx参数的使用demo & t+ H: q( D, x8 A: x7 P& ~8 E, L
`const Koa = require(``"koa"``);`- N" ^* D+ T- f9 ]- z6 M
`const koa =` `new` `Koa();`: y |! d) _9 |2 O
`koa.use(async (ctx, next)=>{`" U- c3 F1 e) _' S% ?6 b6 [
`ctx.body =` `"body可以返回数据,"``;`# [8 Y0 t6 u# h% p5 {. x Q9 O: B: X8 f
`ctx.body +=` `"可以多次调用,"``;`9 q* N5 ^2 Y" S9 B W
`ctx.body +=` `"不需要end()"``;`- t8 I0 ^# v+ x) N/ M) q
`});`
3 Q* G+ Z( J% y, S1 Q/ }, J1 O2 X `koa.listen(3000, ()=>{`& O3 x# e4 l8 V
`console.log(``"监听开始"``);`: W1 j+ Y8 s$ S& u
`});` / |: c+ [( g, v) K, l9 k7 d; Q' H$ Z
效果: - H c0 N6 n, P" {* ^* F! }7 V( d
" ]& G) p' S/ b/ K; P) u
ctx.url ,ctx.path ,ctx.query ,ctx.querystring ,ctx.state ,ctx.type
5 J; k0 `6 i8 ~0 n- P n6 a8 d `const Koa = require(``"koa"``);`) `# J8 C- [8 l
`const koa =` `new` `Koa();`
8 b: R- a/ s8 W, L; M8 L; m `koa.use(async (ctx, next)=>{`0 V. b7 r" b, A6 K, t: ^
`ctx.body = ctx.url;`
# y3 D" j+ l" V6 I `ctx.body = ctx.path;`( H! f/ _: L: S$ E) z, V
`ctx.body = ctx.query;`* r3 _7 |) V: Q, v& e7 [$ a
`ctx.body = ctx.querystring;`* B2 x3 O8 g8 k, E# u2 y
`});`- h" S9 Z6 S+ Q& l: f; x5 ]; R
`koa.listen(3000, ()=>{`7 z" Q* ?; Z0 q$ j4 r
`console.log(``"监听开始"``);`
) T; J" E) m' @. j4 @5 p1 `5 w `});`
' i, i0 j* f( Z/ x& r 访问http://localhost:3000/path?name=sjl&age=18为例,效果图:
/ U T6 c3 N% l* a: L8 a3 ?4 S 1. url: 整个路径 ! m3 z9 ~5 o2 K: U: z
( x" M* f! o0 D r* I1 `1 y: G 2. path: 非查询部分
* h7 M# Y) y' s8 b w - q( [8 Y. Y9 q
3. query: 将查询部分转为JSON对象
" a5 G1 I2 `( q+ X6 W" s ! z# h2 Y. v+ ^& w4 b
4. querystring: 将查询部分转为字符串 8 U7 T8 |8 y. v P& i1 J
3 t; F2 V! L0 @0 ?( t5 { 5. ctx.state ,ctx.type 表示状态吗和类型 2 [6 D; m, C" k- l
2.简单爬虫练习 6 k6 Q* A/ ~ B6 H6 C: [) z% X" y
安装request,cheerio模块
- [* [# d' ]' l7 b( g5 c1 ^: v `npm i -S request: 请求模块`
; p$ w) ^5 D4 u$ ]9 z0 ? `npm i -S cheerio: 抓取页面模块(JQ核心)` 6 S7 X3 p, x) ]5 `
抓取网页数据案例(随机网页)
/ J/ s8 K* Z" o8 q( u& i ~ `//导入模块`9 n. E- M3 v9 |6 P3 e7 p
`const request = require(``"superagent"``);` `//导入请求模块`
3 F' }' o: @6 E2 B+ Z9 d& S/ @0 O2 | `const cheerio = require(``"cheerio"``);`6 J* b8 U. |7 Q6 x9 [8 [
`const {join} = require(``"path"``);`" e7 o5 J1 `* Y
`const fs = require(``"fs"``);`+ j& W# C& d6 [; t+ |. A% ~8 ~
`let arr = [],` `//存放数据`
0 P, X5 [5 q f2 a6 [5 A `reg = /\n|\s+/g,` `//replace中使用`. }& _' Q2 E7 _ C1 y1 P
`url =` `"[https://www.shiguangkey.com/course/search?key=%E5%89%8D%E7%AB%AF/](https://www.shiguangkey.com/course/search?key=%E5%89%8D%E7%AB%AF/)"``;`0 i/ g6 k5 x$ g% G; C
`request`5 c3 Q# ~4 P* F* F1 C, }% z
`.get(url)`
9 u, g3 a: S2 F% r `.end((err, res) => {`
' _7 i# ]+ m. q `const $ = cheerio.load(res.text);` `//把字符串内的标签当成dom来使用`2 T8 `2 k& g+ a/ y: p
`$(``".course-item"``).each((i, v) => {`" u5 ~0 K( T4 j
`// v当前进来的dom,根据网页的布局结构来找到准确的dom节点`
, P& ?+ u" D9 H# Q2 }; i `const obj = {`
. N# ?% h: N( K `imgSrc : $(v).find(``"img"``).prop(``"src"``),`
( `& t/ C1 r# I' {/ F- G f3 a `price : $(v).find(``".fr span"``).text().replace(reg,` `""``),`0 b9 B1 f2 o& F0 _3 g( G4 Q) A$ n
`total : $(v).find(``".item-txt"``).text().replace(reg,` `""``),`
4 w4 e Q8 E5 M6 H4 w `href : join(url + $(v).find(``".cimg"``).prop(``"href"``))`
4 Q% m" L. i( ?8 b; }6 G& P& S `};`3 M" G/ V! V8 v$ U- Y0 B% C
`console.log(join(url + $(v).find(``".cimg"``).prop(``"href"``)));` `//拼接`
! ?4 p8 i8 N* \; L6 |: W/ f `arr.push(obj);` `//把对象放进数组里`
9 w( l2 B- |$ d' p `});`; W4 b# }' Q" s' e
`fs.writeFile(``"./sjl.json"``, JSON.stringify(arr));` `//将爬到的数据写入文档中`
4 x: K* ~' l B0 I4 Z5 b# k `});`
+ O* q# Z; e! e- w0 n D& n" b% W 以上就是本文的全部内容,希望对大家的学习有所帮助 & b/ f# w' q* [! _. Y# j: \: T- E+ ^
# s, U' `2 t4 o
! E, ^" t+ a$ Y& W2 f/ K/ r
6 y# j; d0 L* K
_/ M/ D+ h) x5 d; ]6 | |