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

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

[复制链接]
2 E; ^: q" s5 D( a4 I

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

# p# ?9 j8 P5 U4 v! @% d# I

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

0 u8 }2 x7 F& Y* p

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

2 G/ K7 T3 M$ {& J3 i3 f2 M% u

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

) l) G, U% b3 A, J3 ?7 ~# I

1.koa

6 G& v k: A, g0 l$ o' e$ o8 I: ]

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

7 z0 L. Y; n5 \& @: L5 A; i: \! C

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

实例化对象: const app = new koa;+ |4 ^" E/ c; H0 M! f/ _

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

, s. @7 z, Q& W

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

9 T6 Q: J8 z e& g. t8 N6 W

其中有两个参数:

# F' b: V" l8 E" V/ H8 v

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

8 u- \9 i. Y5 u: e

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

4 e+ d! X9 f) m7 [

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

- w6 Q0 x/ R% b& g2 W3 ~5 X

1. next参数的使用demo

0 [4 F) V" }5 j
`const Koa = require(``"koa"``);` % H4 v2 w1 J$ } `const koa =` `new` `Koa();` * `0 X' c- m& g% r; w$ X5 }% l `//中间件1`5 l, m- }% X. @; X1 }; `" g `koa.use(async (ctx, next) => {`: S7 ~2 t. }( O5 x1 Z1 X `console.log(``"1 , 接收请求控制权"``);` 8 k0 }. Q4 H" G1 t1 z `await next();` `//将控制权传给下一个中间件` ( W4 A8 \1 x# Y) X e# U `console.log(``"1 , 返回请求控制权"``);` 3 y2 E: }8 w: C1 J `});` `//将中间件注册到koa的实例上` X1 G F9 P! n- ^9 V' l( X `//中间件2`6 w5 r _, C0 I `koa.use(async (ctx, next) => {` 8 C9 o3 r. f* X+ C2 ^( G6 {" A5 p `console.log(``"2 , 接收请求控制权"``);`; y3 s! I) O8 v5 j await next();`5 P. {, I) ?/ M Q% i4 s X3 U) _ `console.log(``"2 , 返回请求控制权"``);`7 ^) T! K7 V. o2 A5 Q7 o" K7 Q `});`* _' U# y5 f J; `' H! ^6 ^8 z$ s8 k `//中间件3`- `! \9 ?, M9 l8 j [8 w2 v `koa.use(async (ctx, next) => {` & f, P4 ]0 l! j& C& t- i# l7 Y/ p( h `console.log(``"3 , 接收请求控制权"``);` ; r+ ^ j% f( k- v `console.log(``"3 ,返回请求控制权"``);`7 X# I u3 v C$ [# Q4 k& t1 y, P4 S2 _" v `});`" ?, |9 T- q8 \7 L% L# B `koa.listen(3000, ()=>{` / C' R. U' [+ @2 w5 X% M6 g1 j `console.log(``"开始监听3000端口"``);` + y" E/ ~: p$ y" m" E `});`
7 z! U1 u3 | B) S$ ~# _8 _7 {

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

/ l* @+ {$ r$ q. X4 h7 M( N

访问localhost:3000的效果图;

( R; M; A- r r8 Y$ Q' T
/ i. B2 U s7 K( r% k, z4 ~

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

( M( p/ D6 m8 J' O* a: ?

2.ctx参数的使用demo

- H, X3 i; p0 ]6 O' c* @
`const Koa = require(``"koa"``);` ' X8 O, ~. D; D `const koa =` `new` `Koa();` 3 z q. y/ T7 V `koa.use(async (ctx, next)=>{`+ U/ S6 S7 a l/ |; ^7 v `ctx.body =` `"body可以返回数据,"``;`" Z# \/ }; _. O @. t `ctx.body +=` `"可以多次调用,"``;`& j, C/ l* ~* G+ Q/ R' R `ctx.body +=` `"不需要end()"``;` 0 M5 ]; h; k( I: T, Y `});`& O7 k2 G: z7 _- s* y. l `koa.listen(3000, ()=>{`4 S$ M# ~1 n3 f `console.log(``"监听开始"``);` ~; d; o M5 W! E' s3 \- S" j t `});`
! h' I4 x& a* [. _8 C

效果:

+ ]' w% N: V8 E/ m# d$ x8 N
8 |: I" t1 ]: @0 l: d1 v- q2 P& _

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

0 I, A. e8 A' ^& A2 d& e m% G+ `& M
`const Koa = require(``"koa"``);`2 I# ~ Q5 u- e! R9 u3 I- L `const koa =` `new` `Koa();`- U- v6 K6 C! \1 U `koa.use(async (ctx, next)=>{` % L% c' c4 N* n& C. R7 O1 e' j `ctx.body = ctx.url;`# a( w# A& _2 \ `ctx.body = ctx.path;`& ^* X% x V5 _+ D% q `ctx.body = ctx.query;` 2 n. Q2 I( m( D! G `ctx.body = ctx.querystring;` ! z R) r$ Z' g& [. _7 c' g `});` 1 c6 g# v0 d! o+ c4 Q `koa.listen(3000, ()=>{`9 O5 Z0 M0 b0 s6 T `console.log(``"监听开始"``);` , S* X* g9 D$ i% g6 n( ` `});`
[+ b. n. k# c. ]5 a& p: |

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

: x( q" u. y# d% R/ k: U

1. url: 整个路径

/ U/ I# I+ H& ~ F7 L
; T2 o9 F9 _: o' h7 Y, B

2. path: 非查询部分

0 R" W9 T- d$ o$ J' o9 }
+ o Q( ~8 g) }; X7 f- t

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

3 d( p' X2 u8 f3 p3 _& l" `
) u: J( l& } J

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

: [. j! {" I4 p$ D+ y5 s
' l9 c# s+ z% I' P7 K/ x h1 Z

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

( q2 q6 P3 Y) Y" O7 Z% w

2.简单爬虫练习

: Z3 F5 K( |* g4 f L. h3 l; O4 W0 `

安装request,cheerio模块

, x* e$ Y2 D/ _
`npm i -S request: 请求模块`0 @$ X0 i6 |) [) y( y `npm i -S cheerio: 抓取页面模块(JQ核心)`
$ p! d4 E% g" J8 Y& h& v/ s V" G) S

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

7 h# G7 C4 o/ e
`//导入模块`& \& L0 M! ^; \9 ]. @ `const request = require(``"superagent"``);` `//导入请求模块` " y- H6 r( f* Z# O( {( ^% j `const cheerio = require(``"cheerio"``);`' R; f' n0 {+ k- \9 O! i! f% s `const {join} = require(``"path"``);` T; k( e1 U3 P, {0 S( d! y `const fs = require(``"fs"``);` $ Q1 S! |' i( [0 k `let arr = [],` `//存放数据`2 ]( [' d( t8 F8 ^" \$ j- \7 I `reg = /\n|\s+/g,` `//replace中使用` 1 c/ e% ~$ M) |. }7 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/)"``;` 8 w! ]6 K+ d' Y# i, [) L `request` ! o t8 e) Q: [& I: _8 ` `.get(url)` / t4 \% }' s' }% g) u `.end((err, res) => {`) t% N3 f% r& e: q5 V* p `const $ = cheerio.load(res.text);` `//把字符串内的标签当成dom来使用` ( ^" B; ? y/ V7 b6 `4 F* P `$(``".course-item"``).each((i, v) => {` . W0 F- i' A! k1 S2 W1 T' C7 W `// v当前进来的dom,根据网页的布局结构来找到准确的dom节点` 0 ?% [8 I3 ^, F3 q: R `const obj = {` 0 @) Q( ?) b% w. E* s2 w& l `imgSrc : $(v).find(``"img"``).prop(``"src"``),` . J' r$ u6 g, g. V6 [ `price : $(v).find(``".fr span"``).text().replace(reg,` `""``),`7 U' N# M3 Y; J. T9 k, A `total : $(v).find(``".item-txt"``).text().replace(reg,` `""``),`1 V; J: Y: ]% A! N$ n. P `href : join(url + $(v).find(``".cimg"``).prop(``"href"``))` 8 L4 B4 j& x4 r: j( { `};` 6 K# c0 m4 c" m" r4 } `console.log(join(url + $(v).find(``".cimg"``).prop(``"href"``)));` `//拼接`9 ?% l" o+ r3 \ q `arr.push(obj);` `//把对象放进数组里`6 ^. @5 A b, ^; S |! O! N$ | `});` ! ?3 ]% V2 t+ W( J' j [9 h9 E `fs.writeFile(``"./sjl.json"``, JSON.stringify(arr));` `//将爬到的数据写入文档中`& s. R5 K. c' p3 y' O `});`
' a2 D/ p, n+ ?) ` J6 r" {6 w

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

9 c2 j( }2 ]+ Y3 [- {4 S6 E) V 8 b6 J2 G1 {( C z0 b7 P3 N8 ~ - i( Q" K3 J6 b P+ B. V( g4 b t7 [ 4 b2 f9 ?0 f% Z9 ]/ G ( p5 P: z4 \0 Q) w s
回复

举报 使用道具

相关帖子

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