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

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

[复制链接]
3 j% z1 X: I6 _" j

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

' `: A4 y" A; ?, U$ \6 I

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

! c3 O# Q. n& Z( ?3 F: [- E

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

1 [7 E b/ x. A! f, d- t" t4 v

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

+ i. \! u4 i2 v* l! I! ?

1.koa

" l! C6 C, r& k% J) e7 ]. P$ ^

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

: \9 R+ o7 _0 ^9 H. m( b+ a

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

实例化对象: const app = new koa;; ?" @% Z( u/ t

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

, z3 [: f4 `! U. s$ e; G% E

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

T, ^# T: `$ z, z1 n5 Y; t0 Y

其中有两个参数:

& P- ], ]5 q8 T& L" c% K% A) Q

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

1 H$ a8 Z1 q4 X1 N* E+ k3 \2 J6 ?

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

3 L# S, v$ x' _/ ~6 z

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

* B" g+ i1 ~2 M, [7 _* t5 v

1. next参数的使用demo

- r8 G0 ^4 c9 \4 q1 u! ~
`const Koa = require(``"koa"``);` + b' y' f8 t3 Y- c0 M) J `const koa =` `new` `Koa();`, ^. J8 p( k. B- R/ @% q `//中间件1` # M( i) e% B7 b8 i `koa.use(async (ctx, next) => {` 5 v: U% u5 y6 D* h. k# b* z `console.log(``"1 , 接收请求控制权"``);`& x3 Z- p9 e, b( ~, L `await next();` `//将控制权传给下一个中间件` ' D+ V! }, I0 L& g% H) X1 l+ | `console.log(``"1 , 返回请求控制权"``);`6 ~6 Z& R4 L/ K7 L1 a7 u o `});` `//将中间件注册到koa的实例上` 1 z& u/ y1 l2 H. x2 }! B3 u `//中间件2`1 {, F6 {" Y2 g/ @ `koa.use(async (ctx, next) => {` & \# S, k+ A; t. v `console.log(``"2 , 接收请求控制权"``);` 2 W3 @ j" r5 ]6 N await next();`! a; z/ b; @" B, [" C! U3 d `console.log(``"2 , 返回请求控制权"``);` 1 B% d) {* \) s, e6 x' \$ ^6 w `});`/ K5 i. }% M; S5 e- L2 x* S `//中间件3` . G9 s4 }! e( y: ]# \ `koa.use(async (ctx, next) => {` 5 t; j+ p; l' J8 w# E+ b. G `console.log(``"3 , 接收请求控制权"``);`: @% `0 J E( ^7 N `console.log(``"3 ,返回请求控制权"``);`, H6 W1 B' W/ ?) Z. A, \ `});` $ y4 p, `3 B& F `koa.listen(3000, ()=>{` / b1 `1 T4 |& f' P4 N6 x6 ~ `console.log(``"开始监听3000端口"``);`' J( g- r- Z9 x+ N `});`
: \2 i6 _6 U* t; \& t

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

7 ~* ?8 x! [6 i7 v, a" B7 L9 Y( C: z

访问localhost:3000的效果图;

/ g" |. g0 B$ K) C
. x ?( B" |6 S5 ]4 B

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

* ~2 I1 S6 @" N2 F

2.ctx参数的使用demo

0 Q- C' j- }& `% g, @" j: e
`const Koa = require(``"koa"``);` & V. E( L& V0 {5 L F7 b6 ]7 \ `const koa =` `new` `Koa();` * n, m6 i K% F u! G, z `koa.use(async (ctx, next)=>{` ! X, s2 k2 [* j" D `ctx.body =` `"body可以返回数据,"``;` & e' q2 V% q4 a- n; ^$ ] `ctx.body +=` `"可以多次调用,"``;` ! M. |9 Z% s5 h `ctx.body +=` `"不需要end()"``;`3 p: ?6 Z+ k$ p4 f m: _. V4 A7 x `});` 4 r- @8 z6 g1 \" S m0 w `koa.listen(3000, ()=>{`9 |4 [, I4 r/ T9 c8 ~ `console.log(``"监听开始"``);` + B7 K1 U) N' A: i" H `});`
0 {0 g: R4 Z! s: o8 j

效果:

1 ?# v- p1 H. Z" R# R h! ?( D- D% n
* \+ Q- H& Y4 d0 |3 F

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

0 \9 ~: N5 T$ V l
`const Koa = require(``"koa"``);`/ S \* d$ Z: O" G' P/ y" V6 G) p% L `const koa =` `new` `Koa();` . p8 ?7 ?; u4 f4 H/ [ `koa.use(async (ctx, next)=>{` ) R: a4 e4 G0 S S3 q8 i& P# H `ctx.body = ctx.url;` " W$ [1 ?2 c- A: I- l2 G `ctx.body = ctx.path;`' m3 W: {* i( K6 I' X2 f8 i8 ~ `ctx.body = ctx.query;`: l1 t& I* a3 q# {7 c4 x3 c `ctx.body = ctx.querystring;` 0 z/ |5 @$ K6 ?8 d* n `});`- d% m7 o( f2 A i+ k4 E* Y% e `koa.listen(3000, ()=>{`) d* A, c9 q) L `console.log(``"监听开始"``);` 4 c# o. J& B4 G! n. ^ `});`
+ b7 U& S4 J; T ]

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

9 B& q! }% o6 E* [6 B

1. url: 整个路径

* H, w/ F6 q# K7 g$ o& f# |9 G
1 @( o% Y& D7 V0 j

2. path: 非查询部分

4 i/ r% t- @0 h0 p% w" c7 y
7 h$ w+ `: e. K# Z6 I7 V- ?' v, L

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

* k+ o1 L- Y1 V2 D1 o
: |- z4 M$ W. x& h, m; S# r7 _

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

- m) I* D3 f( ^+ q8 o; A
6 U8 {0 q S4 |% b J+ k1 A% |

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

7 ]) C/ k4 \( A

2.简单爬虫练习

" q$ L1 O3 t. h+ o" \

安装request,cheerio模块

) Q2 N# d9 R% x' e3 [
`npm i -S request: 请求模块`' X( [+ n0 S' y6 X+ d* p `npm i -S cheerio: 抓取页面模块(JQ核心)`
D4 o4 V5 i F+ y* T

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

7 L$ c! ?! q, Z( p) x" E' Z9 M- ?
`//导入模块`; R7 j5 x" e8 U8 x `const request = require(``"superagent"``);` `//导入请求模块` 6 f# u0 ^ Y6 u$ K `const cheerio = require(``"cheerio"``);`4 ^* ?) J. H5 f) M+ s `const {join} = require(``"path"``);`" c% X+ ?1 `- w4 C `const fs = require(``"fs"``);`+ ^$ S, E% I) b$ C1 ~; }/ h5 k1 P `let arr = [],` `//存放数据`% E4 N/ {3 g& |- S0 _9 K `reg = /\n|\s+/g,` `//replace中使用`% _# W% g# k) m; ~& |6 l6 j5 } `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/)"``;` X) a# Z, x) T5 c: j2 u `request` * Y; m# l3 V- R1 ? |, w `.get(url)` & J- z* Q& `( X8 P) m2 Y) e `.end((err, res) => {`( p% O" ^9 P: o# A- I `const $ = cheerio.load(res.text);` `//把字符串内的标签当成dom来使用` % G* Z" T" H+ g- t6 N `$(``".course-item"``).each((i, v) => {`8 S, D4 ?8 |6 ^3 N' z% k) B6 j. } `// v当前进来的dom,根据网页的布局结构来找到准确的dom节点`# y8 Z2 e) b" C2 w5 D$ z `const obj = {`# q1 k) Z& e( ~. f, X+ v `imgSrc : $(v).find(``"img"``).prop(``"src"``),` b6 g, {: ?1 U8 }' b; _ `price : $(v).find(``".fr span"``).text().replace(reg,` `""``),`8 A" Y1 _- m9 h+ R( E `total : $(v).find(``".item-txt"``).text().replace(reg,` `""``),` 5 F0 f" q2 X4 ^: I# w* r `href : join(url + $(v).find(``".cimg"``).prop(``"href"``))` # e: [8 T9 I" J- k6 G `};` ) V& `% x1 p, k" z8 }/ x% i- O @ `console.log(join(url + $(v).find(``".cimg"``).prop(``"href"``)));` `//拼接` + J- T. V9 T3 L: b4 D `arr.push(obj);` `//把对象放进数组里` + n4 \6 K/ f+ R+ | `});`( C1 E" e: X! @$ ~3 O' n6 P: o" p4 q `fs.writeFile(``"./sjl.json"``, JSON.stringify(arr));` `//将爬到的数据写入文档中`5 E, G- _* e7 z3 v/ q. a" d% ` `});`
' O; X7 @8 h N. v; g, i; p* S4 d2 V

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

" M; Y) \/ R( w, I" O ; L: S, M5 ^, W$ h' r8 Y p" q1 i2 p+ ] 5 \0 W3 _ T( R* q & F, c! D5 ^% r! G9 N- f # l1 M6 [4 m/ i# f5 X" ?
回复

举报 使用道具

相关帖子

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