|
% @) h7 ?6 t) E/ A Koa -- 基于 Node.js 平台的下一代 web 开发框架 " a- |9 }7 k/ j' _+ a
koa是由 Express 原班人马打造的,致力于成为一个更小、更富有表现力、更健壮的 Web 框架。 使用 koa 编写 web 应用,可以免除重复繁琐的回调函数嵌套, 并极大地提升错误处理的效率。koa 不在内核方法中绑定任何中间件, 它仅仅提供了一个轻量优雅的函数库,使得编写 Web 应用变得得心应手。开发思路和express差不多,最大的特点就是可以避免异步嵌套。koa2利用ES7的async/await特性,极大的解决了我们在做nodejs开发的时候异步给我们带来的烦恼。 5 ^+ o- k, J8 F- p7 N- P
英文官网:http://koajs.com
2 u* I' h+ c4 h 中文官网:http://koajs.cn
6 G% F2 l/ Q7 k) \9 y0 C 1.koa . ^9 e, s: B: |# H6 u
安装koa包: npm i -S koa@latest
4 j8 g/ P1 T6 A& L 引入: const koa = require("koa"); 实例化对象: const app = new koa;; v2 H# a* P$ f/ k: h& [0 M
通过实例操作,专门用于客户端请求的函数叫做中间件,使用use()注册
* e. E. [2 o& W use()函数中必须使用异步 async; use可是调用无数次; ) x+ h. K | N( U
其中有两个参数: # \. V& _, Q) | L6 a
a)ctx: 上下文环境,node的请求和响应对象,其中不建议使用node原生的req和res属性,使用koa封装的requset和response属性 2 w: U1 x$ i8 }9 O0 w# |9 Y
b)next: next(),将本次控制权交给下一个中间件。 6 p1 [3 N. G9 O9 |
最后一个中间件使用next()无意义,执行完控制权返回上一层,直至第一个。
3 a! ?' W* O( z; n+ L 1. next参数的使用demo . Z, U; M2 ]) f# I
`const Koa = require(``"koa"``);`
7 q1 [$ g& M; N" R `const koa =` `new` `Koa();`/ `7 J9 Q9 D X! _. j
`//中间件1`! J( r( V$ I6 Z
`koa.use(async (ctx, next) => {`
# v" x( ^& R' E$ _. F* \ `console.log(``"1 , 接收请求控制权"``);`$ S; O. X( ]" z, h% J
`await next();` `//将控制权传给下一个中间件`5 M; G* z: ^9 G* ~2 L8 h. T1 p7 h
`console.log(``"1 , 返回请求控制权"``);`
- f7 G+ X! f9 x8 c9 C! ?! k7 @. S, r `});` `//将中间件注册到koa的实例上`7 J5 Y# O9 T, c3 T- t7 I5 h
`//中间件2`
8 ^* f3 z B7 ^$ U, c `koa.use(async (ctx, next) => {`8 A: @) V( w: C% O+ F2 V& v
`console.log(``"2 , 接收请求控制权"``);`
2 g' n9 i2 _5 y* M5 V await next();`' o+ Y: s- k3 i, f1 X; Q) R' u
`console.log(``"2 , 返回请求控制权"``);`9 Q% b- d7 X. n" M5 X. t. W
`});`& k9 m7 i% r. {( w6 O+ P: b
`//中间件3`. y: n$ x; c. n: d" o7 s' {
`koa.use(async (ctx, next) => {`
' j* O7 m: Y: d) I& T f; r" Z `console.log(``"3 , 接收请求控制权"``);`" M o- z; u! u; {3 v! p
`console.log(``"3 ,返回请求控制权"``);`
+ u0 r* L, O* Z6 y `});`
! a( G u: ?9 B2 n `koa.listen(3000, ()=>{`& B; t' K) y3 ^* k
`console.log(``"开始监听3000端口"``);`
) g- ^8 ]' q0 s' T- J `});`
. L6 }& o1 ?8 x7 `$ L5 E# q 注:当中间件中没有next(),不会执行下面的中间件 5 N5 G( f& r! K+ I) Z% P3 x! m
访问localhost:3000的效果图;
3 w& d: N+ P: s; e
2 m8 f) ?; L1 l7 V7 l6 q5 a 注:会有两次操作是因为图标icon也会请求一次 / s5 \3 _; p. F
2.ctx参数的使用demo
1 Q1 F8 Y* U( _) z5 u' b `const Koa = require(``"koa"``);`
3 K, {7 T1 | a% b `const koa =` `new` `Koa();`
% B x4 j, n' `5 A `koa.use(async (ctx, next)=>{`, I0 K0 K) i8 c6 L. ~* {
`ctx.body =` `"body可以返回数据,"``;`& i! s% D- b6 g# c% I
`ctx.body +=` `"可以多次调用,"``;`2 @* n0 U" S+ N5 K, i4 n$ z9 w
`ctx.body +=` `"不需要end()"``;`
4 _% b; f9 p/ I+ r4 |/ O `});`
8 n+ m! n# C L" W0 l& C `koa.listen(3000, ()=>{`
% ?. P/ [+ }( \+ X- O `console.log(``"监听开始"``);`; x+ f1 M3 \6 K
`});` , d4 L0 O5 W+ d m" f: A+ O
效果:
+ w3 n0 b, F2 Y3 R7 B8 w8 N& J; B! v8 u1 g o- _0 ~; h8 Y# W5 j) U& n* g. z
ctx.url ,ctx.path ,ctx.query ,ctx.querystring ,ctx.state ,ctx.type & ^6 n, O: f( l8 o" t
`const Koa = require(``"koa"``);`& g; T' F/ _6 w# U4 V/ c
`const koa =` `new` `Koa();`0 |! p+ m' i% {/ s( k" z4 ]
`koa.use(async (ctx, next)=>{`! N M u* P0 T( Q: G' T
`ctx.body = ctx.url;`5 h; Q+ Z% t; Y" u& v! ~- C# D
`ctx.body = ctx.path;`8 |0 N, a6 j' W1 i" i' {! ^' ~$ f
`ctx.body = ctx.query;`3 F; D8 H) |+ v. V0 Z
`ctx.body = ctx.querystring;`
7 G% R3 i: W: J1 _, H8 Y `});`
6 M6 [8 t0 u+ E" D$ o `koa.listen(3000, ()=>{`4 Z6 D- q, \+ k9 P7 r7 ^. u
`console.log(``"监听开始"``);`5 L7 A: Y+ T; e2 F' T& V
`});` % Z p4 @6 m+ y t6 m) V- D( z- O. D
访问http://localhost:3000/path?name=sjl&age=18为例,效果图:
" k; \; W) O% j* Q$ R/ I x* m- W 1. url: 整个路径 # [# S/ \3 _+ L, u6 K! a
- ^6 N. \, ]) D2 r' R 2. path: 非查询部分
/ V1 h; Z6 e7 M4 c- g
9 G/ R3 ^; ^: }! e* ~ 3. query: 将查询部分转为JSON对象 / |9 {6 Y. }- r# d
{- z }/ z/ a0 q
4. querystring: 将查询部分转为字符串 . L8 L0 c6 C" g$ Q
+ J; X' H; \0 y% x5 V% g0 }6 n# ]- \
5. ctx.state ,ctx.type 表示状态吗和类型 ; T( G( j4 A$ \* ]- {
2.简单爬虫练习 6 ?0 N+ k5 i2 }6 {
安装request,cheerio模块 & ?# P$ G" I4 ~8 x1 r- v- @# d
`npm i -S request: 请求模块`
1 Z3 L- f5 Q; G# c* E8 X) \9 g `npm i -S cheerio: 抓取页面模块(JQ核心)`
8 S! M7 @4 v/ R- g) d+ Z7 u, S 抓取网页数据案例(随机网页)
2 ~% {$ |( R+ Y0 v5 {" ~ `//导入模块`7 d$ a: W( Q) j2 T5 t
`const request = require(``"superagent"``);` `//导入请求模块`( G: M- t1 h# _2 `
`const cheerio = require(``"cheerio"``);`
# `( K. f j% F8 P6 A% a: g `const {join} = require(``"path"``);`
, A1 ~# a9 i: e/ y) N4 K& M `const fs = require(``"fs"``);`4 e- e( y, p0 }# j
`let arr = [],` `//存放数据`4 F' z3 s( q3 H/ N
`reg = /\n|\s+/g,` `//replace中使用`
& K" x) Y+ g, ~ K) r- ] `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/)"``;`
' `; u" N4 ]& J4 T$ H6 a& m7 u `request`
( Q" _* b( h8 K# r% e `.get(url)`8 \: Y* h. j2 b D
`.end((err, res) => {`" b1 S3 u/ u( c% l3 o: h) o/ G
`const $ = cheerio.load(res.text);` `//把字符串内的标签当成dom来使用`
J& B1 S9 X' d) Q3 p6 R: Q- R5 ~ `$(``".course-item"``).each((i, v) => {`
; i2 P/ S+ t9 d/ j' |. C8 a `// v当前进来的dom,根据网页的布局结构来找到准确的dom节点`
* r( x4 X7 |2 d7 S `const obj = {`
( U- B1 F, [; |6 a6 d `imgSrc : $(v).find(``"img"``).prop(``"src"``),`
. H9 w/ c( V% j4 p$ t `price : $(v).find(``".fr span"``).text().replace(reg,` `""``),`
" W" H+ {; X6 e: m9 ]$ ^ `total : $(v).find(``".item-txt"``).text().replace(reg,` `""``),`
2 U6 J" I1 F7 k6 U, t0 b0 _- \3 V/ q `href : join(url + $(v).find(``".cimg"``).prop(``"href"``))`4 w1 q; d0 y: e
`};`0 B, r2 F/ {: N+ `; l
`console.log(join(url + $(v).find(``".cimg"``).prop(``"href"``)));` `//拼接`8 D. P- P2 l+ `- C. m# p
`arr.push(obj);` `//把对象放进数组里`
( e; z7 k- i/ U: J0 t* e `});`/ {: M# p8 p# b
`fs.writeFile(``"./sjl.json"``, JSON.stringify(arr));` `//将爬到的数据写入文档中`( W1 l" A$ b9 g; A: P+ j6 G
`});`
9 V9 m1 c7 L7 f' B& V 以上就是本文的全部内容,希望对大家的学习有所帮助 : T+ j! {- G6 r9 f; J
3 _. p! d M" B# H1 B
( I$ @+ h3 b: Q# b* K4 [- m5 x* ~
; `1 \& j8 R f# {# v' M0 F2 x6 ~1 w% Q/ t6 w
|