收藏本站 劰载中...网站公告 | 吾爱海洋论坛交流QQ群:835383472

node.js学习笔记之koa框架和简单爬虫练习

[复制链接]
w x* R' v; U" x* q8 g8 _

Koa -- 基于 Node.js 平台的下一代 web 开发框架

. T* }6 C% ]3 U/ v' t7 {6 C, R8 h

koa是由 Express 原班人马打造的,致力于成为一个更小、更富有表现力、更健壮的 Web 框架。 使用 koa 编写 web 应用,可以免除重复繁琐的回调函数嵌套, 并极大地提升错误处理的效率。koa 不在内核方法中绑定任何中间件, 它仅仅提供了一个轻量优雅的函数库,使得编写 Web 应用变得得心应手。开发思路和express差不多,最大的特点就是可以避免异步嵌套。koa2利用ES7的async/await特性,极大的解决了我们在做nodejs开发的时候异步给我们带来的烦恼。

6 R& p! J! i: |7 R7 @( U

英文官网:http://koajs.com

* h- |+ O. G. y; i4 r- b5 m

中文官网:http://koajs.cn

) J s7 O8 o6 D

1.koa

4 Q8 C- c7 t3 s3 ^9 v& y6 a

安装koa包: npm i -S koa@latest

, Z/ r& R2 ~. m7 G! z: G* e& J5 m

引入: const koa = require("koa");

实例化对象: const app = new koa;) Q, U9 V" s: [' `6 j) h l# w

通过实例操作,专门用于客户端请求的函数叫做中间件,使用use()注册

* Q: [2 k/ d2 j4 e+ p- l# V

use()函数中必须使用异步 async; use可是调用无数次;

0 B" w3 \: v4 p& z) n: Z& h) o

其中有两个参数:

7 ~$ `: j$ L$ @$ J

a)ctx: 上下文环境,node的请求和响应对象,其中不建议使用node原生的req和res属性,使用koa封装的requset和response属性

7 Q! N) |- e! \0 X% j; W7 d

b)next: next(),将本次控制权交给下一个中间件。

& x# L' X$ v; b

最后一个中间件使用next()无意义,执行完控制权返回上一层,直至第一个。

7 s. w; }; Y; ]# [9 ?5 \1 d

1. next参数的使用demo

8 p6 `- q6 N3 M& D9 K% A! R
`const Koa = require(``"koa"``);`6 N- ~4 [8 a1 D: p; h0 G- r `const koa =` `new` `Koa();`7 i3 x1 @) d; e3 v' H0 o5 o5 S7 i+ Q4 p `//中间件1`7 D. h! \1 Y1 r6 P! \ `koa.use(async (ctx, next) => {`. Z. E# f# z( q+ W a* Q9 l `console.log(``"1 , 接收请求控制权"``);` $ a2 ?) a3 y; I/ K! c4 _ `await next();` `//将控制权传给下一个中间件` h9 {$ T- K' J `console.log(``"1 , 返回请求控制权"``);` ' f$ F: D% k: I! @: f/ ]' ] `});` `//将中间件注册到koa的实例上` / ^/ g' r: G. i, C7 c4 K `//中间件2` % k/ Q! L2 }$ C* P- @ `koa.use(async (ctx, next) => {` 5 b7 X. [/ h: w/ A1 d `console.log(``"2 , 接收请求控制权"``);`8 i8 @/ \7 i: q6 U, o5 L/ q( P. b await next();` ; h" @7 V. y9 u1 {* L6 h2 [ `console.log(``"2 , 返回请求控制权"``);`" J3 h3 S1 X( k% }; t% ? `});` , g7 [/ e4 z! Z) L: _/ P1 W4 F `//中间件3`* R; V2 @& W+ W8 d `koa.use(async (ctx, next) => {`( U% B3 Z; {5 s7 M9 j) W' K0 A `console.log(``"3 , 接收请求控制权"``);` & S+ @* M1 Y+ u2 T6 b4 N* h `console.log(``"3 ,返回请求控制权"``);`6 n# Q& l0 A8 f, K `});` ) h, c0 j+ @; Q+ v `koa.listen(3000, ()=>{`7 h+ X/ t O# t6 L3 n `console.log(``"开始监听3000端口"``);` $ D" Q) s/ @/ G* ^( F9 A" [- C `});`
5 ~+ N3 N+ r0 i9 A: H0 Q* [6 I9 B

注:当中间件中没有next(),不会执行下面的中间件

' O6 t' r: K) Y

访问localhost:3000的效果图;

* Y7 B8 C5 D% t0 a3 s
+ K. E& G9 _6 F, J; J2 q, k

注:会有两次操作是因为图标icon也会请求一次

2 V S' `9 e# A* u/ N7 n

2.ctx参数的使用demo

6 x: g4 l5 _( l; B" N& X; F
`const Koa = require(``"koa"``);`3 a1 v5 T `6 f6 `5 M `const koa =` `new` `Koa();` 5 s) i; x" }( n" }; V2 E" w: |5 J9 V `koa.use(async (ctx, next)=>{` ) T# f( b" v% v `ctx.body =` `"body可以返回数据,"``;`) R& O* @% f! ~& J* k `ctx.body +=` `"可以多次调用,"``;`& P1 `+ H; r4 Y" L3 O, i5 Q' U `ctx.body +=` `"不需要end()"``;` ; k0 D3 H+ ^2 o: {7 B* d! O `});` 2 T$ q; [) @5 c) K+ k `koa.listen(3000, ()=>{` 9 K9 a t; {2 ^* M2 Z `console.log(``"监听开始"``);` & r% N e6 X) V3 Y `});`
7 \) k4 f8 X8 }/ S2 b

效果:

' v3 M, @- c6 f& ?6 {; ` W
5 t% `$ ~7 G7 y, ~

ctx.url ,ctx.path ,ctx.query ,ctx.querystring ,ctx.state ,ctx.type

( V q% }# u S. o" X) ~' f
`const Koa = require(``"koa"``);`& g1 G& e% n0 N4 J# {: W M# o `const koa =` `new` `Koa();` : D# T5 a( z( F* g8 m4 n `koa.use(async (ctx, next)=>{` , {2 C' y( O3 V: `8 u5 s `ctx.body = ctx.url;`1 p; k* B9 p$ R& y `ctx.body = ctx.path;`/ t' Z: F( v1 n4 |0 L. R0 E `ctx.body = ctx.query;` 6 s# u+ `# H c$ A! }3 ]/ l, p `ctx.body = ctx.querystring;`& D5 z; C; p) C, }* U" }+ \# j3 p5 T `});` Q' B5 h2 v) h: F `koa.listen(3000, ()=>{` 3 \: o7 b, t" `; J/ E1 `# j: ] `console.log(``"监听开始"``);` % E. C! s' n) k* j `});`
9 {& O/ z; K+ l0 w7 p+ ~' ]

访问http://localhost:3000/path?name=sjl&age=18为例,效果图:

' Y; J! ]" g/ ^* G: m! E

1. url: 整个路径

' F, }! V' R7 i- [( w2 L1 y9 L' q
, x, T* _0 J" P/ p5 H: S

2. path: 非查询部分

2 O+ d/ l) B2 J0 w3 S1 @
5 A) Y% E5 i& W) |0 B+ h9 N3 ~

3. query: 将查询部分转为JSON对象

2 o9 l* Z& [' G& P, c1 Q' J
k% q8 M# I: \5 e

4. querystring: 将查询部分转为字符串

& W8 S) Z* W1 {
* e! O: G* o6 {0 [

5. ctx.state ,ctx.type 表示状态吗和类型

8 H8 p$ c* k3 B B7 i) K2 d

2.简单爬虫练习

: k0 L! e" w0 M2 q4 U! w

安装request,cheerio模块

% b/ @, w; W- W4 H) m5 D- ?( s! w& T
`npm i -S request: 请求模块`. L$ H# f" M$ r* n `npm i -S cheerio: 抓取页面模块(JQ核心)`
, ~& s; r( N4 H: |! D& u

抓取网页数据案例(随机网页)

% N6 v6 [/ s( c4 W- Q
`//导入模块` - O# d* o* A4 _: C6 h* n `const request = require(``"superagent"``);` `//导入请求模块`' @/ A" D+ A5 q5 C, F0 Q `const cheerio = require(``"cheerio"``);` , ~4 f6 N$ j5 d% ^; P `const {join} = require(``"path"``);`1 b T% M7 q( l" W V% B# j `const fs = require(``"fs"``);`6 H" s2 d- f" t3 B `let arr = [],` `//存放数据` ( v) G/ J. X6 Y6 h2 H3 { `reg = /\n|\s+/g,` `//replace中使用`$ `6 L; C- f' i `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/)"``;` W# ?' C% \ X& Z( ^ `request`0 }8 _6 _3 ^4 @* n5 M9 p2 w5 Y- o `.get(url)` 3 c- v6 @; P8 C4 z% Z* w# h8 Q5 N9 F `.end((err, res) => {`& ^* v# B. [: t/ i% H `const $ = cheerio.load(res.text);` `//把字符串内的标签当成dom来使用`2 Q4 A3 X' {. U; \ `$(``".course-item"``).each((i, v) => {`7 J6 j* y/ _& K! U5 v `// v当前进来的dom,根据网页的布局结构来找到准确的dom节点`3 w0 ^- k4 v+ J/ ~4 b `const obj = {`- |* ]) I' _5 P `imgSrc : $(v).find(``"img"``).prop(``"src"``),` }; {7 C9 {( D& Z, `2 H `price : $(v).find(``".fr span"``).text().replace(reg,` `""``),` . I }) J* w- M8 w! y `total : $(v).find(``".item-txt"``).text().replace(reg,` `""``),` * a8 V0 ~0 M& G/ u. t `href : join(url + $(v).find(``".cimg"``).prop(``"href"``))` & @5 y- q# x# R# }+ f `};` ( p, x" `* U2 `2 U( T6 {7 ~ `console.log(join(url + $(v).find(``".cimg"``).prop(``"href"``)));` `//拼接` , H3 B( F9 |4 e; z2 w4 p `arr.push(obj);` `//把对象放进数组里` 9 i6 c' V1 h0 L0 e, d `});`: a; d/ ^' D6 f& V/ t `fs.writeFile(``"./sjl.json"``, JSON.stringify(arr));` `//将爬到的数据写入文档中` ' G+ I9 c X! P9 W1 o! X( O `});`
0 k% ?! ^8 ]" W- N! |1 Z

以上就是本文的全部内容,希望对大家的学习有所帮助

/ q% R$ E- O# [: v6 C U- u% J" T. y! K& Y5 ~ 1 [0 i F5 A; ^7 {- j3 Y2 C : a8 n$ r% A* D+ e) O b( S1 m0 h& M. q1 p
回复

举报 使用道具

相关帖子

全部回帖
暂无回帖,快来参与回复吧
懒得打字?点击右侧快捷回复 【吾爱海洋论坛发文有奖】
您需要登录后才可以回帖 登录 | 立即注册
邢雷
活跃在2026-4-7
快速回复 返回顶部 返回列表