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

[复制链接]
+ b9 y {( T$ |8 J( c7 G

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

6 J% b$ [& ^3 }+ @) u- M

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

7 V& V4 \' a- c0 _

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

8 Q0 g9 _1 C# M' g

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

3 v7 W& ?/ c& O

1.koa

8 L* `+ K0 L2 C. r; ^% o6 N$ b

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

4 L7 \) M; u+ ?4 a. n% c

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

实例化对象: const app = new koa;- w% W( E% X% [$ l( j

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

, Y" ^$ w# Z( P% R' P9 v

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

) K$ E9 l ?1 F& w+ J/ g! n

其中有两个参数:

' j0 Y/ s: O7 @1 ?( v

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

& ]; ~& g, ~5 @+ O2 e2 v

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

% E' [6 r: J2 l' y/ J4 F8 {

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

4 T8 R+ |3 p2 L$ \% K% T' Q

1. next参数的使用demo

, O; R4 _; F; P/ a0 Z
`const Koa = require(``"koa"``);` 0 m) w# }6 @8 A7 o `const koa =` `new` `Koa();`4 T8 l4 N2 z7 F5 ?9 ] `//中间件1` ) w; D! A, k% ]& x' R' t8 A `koa.use(async (ctx, next) => {`( B f% h" c- n `console.log(``"1 , 接收请求控制权"``);` h; |4 ?2 S# t( e0 K9 j `await next();` `//将控制权传给下一个中间件` . c& a7 @# V3 o2 W `console.log(``"1 , 返回请求控制权"``);`- U! w! y1 n2 U6 H- M `});` `//将中间件注册到koa的实例上`! { I p; p3 `. S7 m2 ~ `//中间件2`" Y" Y* i2 o" q) {2 p `koa.use(async (ctx, next) => {`5 s# e j7 I) U6 \7 V3 m/ t6 @ `console.log(``"2 , 接收请求控制权"``);` 8 H. M) [. M7 u$ E await next();`. v X3 @' _* s8 G+ P1 s `console.log(``"2 , 返回请求控制权"``);` . b2 } X- V3 | e `});`$ p& _; e$ S6 R- S2 Q `//中间件3`9 g0 F2 z/ H" W u `koa.use(async (ctx, next) => {`5 G7 I: A$ z D `console.log(``"3 , 接收请求控制权"``);` 8 r( ^$ Y( D) G! C `console.log(``"3 ,返回请求控制权"``);` 8 B8 i+ K4 Y0 s5 H ~ `});` : ]4 m7 j- E) ^ `koa.listen(3000, ()=>{`8 S% @4 i& w- N# D' ^$ R `console.log(``"开始监听3000端口"``);` 1 C" B4 ?1 @; g8 a7 W `});`
9 }4 u/ N- ~9 `- o! B

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

( z7 a2 ]5 b3 N6 W2 X C

访问localhost:3000的效果图;

' t5 ?* `: A( l* s* B& B9 O
X1 [. q+ c4 v% j K6 r

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

. C p) y& _: n6 R1 Q% R, F$ D

2.ctx参数的使用demo

3 F* E1 G; U0 P" n+ E1 i
`const Koa = require(``"koa"``);`, O- I) d5 I0 `& X `const koa =` `new` `Koa();` w3 g8 A( i% N/ c0 I7 l, ? `koa.use(async (ctx, next)=>{` " }1 f; \/ |" s( f" B' I `ctx.body =` `"body可以返回数据,"``;`/ x4 ?2 h U1 ] `ctx.body +=` `"可以多次调用,"``;`# h. [' O: e/ f2 l8 s$ q `ctx.body +=` `"不需要end()"``;` * z0 B7 y3 K" b$ X% @% V `});`* i5 E* e7 W6 f9 ]6 P9 G `koa.listen(3000, ()=>{` " g% X1 X s) V0 Z `console.log(``"监听开始"``);` / `, P+ R5 V& ?, L: V `});`
) h: i, L% N1 m$ w0 ?

效果:

: T% N! X' ~5 ?
, K/ P$ x3 Q( p# W, u: ?

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

7 M& a4 K- w" {) n5 c5 w
`const Koa = require(``"koa"``);` & ?9 c* x+ S5 ^- v; Q `const koa =` `new` `Koa();` % c/ m# v/ Y9 n! Q; K q `koa.use(async (ctx, next)=>{` 4 Y# t1 Z% Y/ W4 Z \# b8 h/ Q `ctx.body = ctx.url;` ! W8 I* R/ x8 q/ o9 }! k G `ctx.body = ctx.path;` L0 w1 o# N, m( ?* K' p4 u `ctx.body = ctx.query;` ; H6 D; u; ^+ g4 { `ctx.body = ctx.querystring;` ( q1 ^7 H' R( G0 T S `});` 7 ]0 I) W' b- N7 Y1 M$ w `koa.listen(3000, ()=>{`/ L0 {5 G+ i# ?, X `console.log(``"监听开始"``);`2 B% L' f, C |6 u- R `});`
0 f" g3 W( M7 Z( J

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

$ o; R( K' ~ D1 H/ J" p$ v

1. url: 整个路径

1 t6 A! P3 s6 J: {
7 e3 ~& N5 S" b9 o- p

2. path: 非查询部分

8 q; \9 f+ H% e. z! p ^: E" A
+ T5 Y* s0 H1 C. ~; r \( C

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

5 @7 H6 |: n: _$ ]- P) E) C8 \. l
. L6 x+ g! j: p' M: T5 x0 k

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

# G- j* l" j, _4 h8 g
* p8 G2 [2 W& C& _; r; y

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

' ~1 }2 t! z: O% H

2.简单爬虫练习

/ P6 F# j7 {9 S" H. a

安装request,cheerio模块

* Y N! ~4 j- f: r/ Q8 v2 Z
`npm i -S request: 请求模块`/ g+ o, L9 i9 f) _, J `npm i -S cheerio: 抓取页面模块(JQ核心)`
* d* S+ p( Q% @0 D3 H# A* u9 i% Y; ~

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

3 ]" ?% J" h9 _. s0 D
`//导入模块`( _" H" \. f) t; u T+ v, V `const request = require(``"superagent"``);` `//导入请求模块`: F: U2 k b+ T! t- y `const cheerio = require(``"cheerio"``);` ; k& b% t! q! G' u6 v/ d- l% \ `const {join} = require(``"path"``);` 6 ^+ g. { f5 J+ P% ]. S: _. j `const fs = require(``"fs"``);`: C/ V3 v$ Q1 k; H `let arr = [],` `//存放数据` 3 c2 D, c+ C; M D: s `reg = /\n|\s+/g,` `//replace中使用`1 K" K- C* m, 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/)"``;`; e; m# x3 R$ Y! Q+ o9 L2 C- W `request` 0 }# m9 h% B4 O/ l `.get(url)`! ~+ }( o$ k9 ?! t2 I `.end((err, res) => {` 3 G& E' I2 G. ]: f' Y% P `const $ = cheerio.load(res.text);` `//把字符串内的标签当成dom来使用` 5 r \& {: o4 ~( u `$(``".course-item"``).each((i, v) => {` ; k/ H5 q" T- B1 j& ~% a `// v当前进来的dom,根据网页的布局结构来找到准确的dom节点` # ~/ g, J/ {- B% |5 W! B `const obj = {`" {% n& \. ]. i5 P. b3 s( R `imgSrc : $(v).find(``"img"``).prop(``"src"``),`% M3 I6 i/ o# `% ~/ w. E `price : $(v).find(``".fr span"``).text().replace(reg,` `""``),`' M- N3 y6 h/ A/ [ `total : $(v).find(``".item-txt"``).text().replace(reg,` `""``),` * h1 i$ v. D/ Z# l, T# w `href : join(url + $(v).find(``".cimg"``).prop(``"href"``))`% B* r. R8 D' Y7 B& h3 S1 b: I `};`8 H& R7 b7 Z: e- O) a9 l" n `console.log(join(url + $(v).find(``".cimg"``).prop(``"href"``)));` `//拼接`2 I: V) R+ p8 U9 ]5 f3 a3 [; U+ ^ `arr.push(obj);` `//把对象放进数组里` 0 H0 D4 T! M( B) Y8 ^+ f, F/ m `});` " b# L! n' T- U0 H `fs.writeFile(``"./sjl.json"``, JSON.stringify(arr));` `//将爬到的数据写入文档中`; r1 B. F) F+ H. L `});`
( K4 c1 O8 D9 r- \

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

a, P5 b/ Z' v- U% b4 S. H, y. g . I' G+ H3 j) } $ T1 ?, r, @3 X) K. l, ^3 T, `* _: a$ ^% | # e X: b; L$ ^9 R) @: i
回复

举报 使用道具

相关帖子

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