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

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

[复制链接]
; P( R+ m% D1 E' |

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

; G1 [! F6 K# W9 Y5 q

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

# ]6 Y3 M1 W- K7 Y

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

7 B; g6 B6 m* s9 V$ w- d

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

$ Y& x. z+ ^ H" l

1.koa

: A" B& C2 D3 P

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

7 M0 M/ t; f$ w

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

实例化对象: const app = new koa; / B3 @' N* q+ `7 w6 V5 W

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

* W+ o' Z- A1 ]; v2 Z

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

7 q- ?: Y+ x: B! n4 e5 s+ }

其中有两个参数:

4 E8 @+ d4 y. f$ F+ N& I

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

4 Y) c. d0 }' u* l. v

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

E$ @/ a$ @$ a; c' d0 U4 u

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

( B# _5 o# V$ l8 q3 V t# u' m

1. next参数的使用demo

6 O3 s/ m$ i5 S3 f/ I' m
`const Koa = require(``"koa"``);` - c$ t9 q, z: W `const koa =` `new` `Koa();`5 N+ T4 S: U( z z `//中间件1`* i" b4 a6 A' b7 _ `koa.use(async (ctx, next) => {` , S( ^* h, T/ f5 d1 [8 h+ t! U `console.log(``"1 , 接收请求控制权"``);` ' n1 A" I: | C8 U: j& o `await next();` `//将控制权传给下一个中间件`+ c& t$ P& i8 _* |$ s t `console.log(``"1 , 返回请求控制权"``);`' g# l1 p3 s0 H% b4 g `});` `//将中间件注册到koa的实例上`8 q1 H# S& Y2 z5 d6 o) n `//中间件2` # U. u# B! O0 Z2 V! Z& e `koa.use(async (ctx, next) => {`. [* P$ J2 K: b- ~ `console.log(``"2 , 接收请求控制权"``);`+ O9 m8 q7 i5 A8 X {9 {0 @ await next();` 1 Y3 s" u5 x G$ | `console.log(``"2 , 返回请求控制权"``);`' C6 D g. ^9 \$ \9 g' O1 _" } `});`' m7 X3 `6 w* f p5 j$ g `//中间件3`2 T9 Q6 d+ U8 \- B. X) i1 G `koa.use(async (ctx, next) => {` ?$ q* F* n0 Q& [7 S `console.log(``"3 , 接收请求控制权"``);`# `7 E8 S I% m `console.log(``"3 ,返回请求控制权"``);` # j& J1 O& f/ _4 e& v7 E' h0 h3 j `});` + |& x2 J, \) K9 f" p `koa.listen(3000, ()=>{`! x1 S: N: V& a$ i5 ~ `console.log(``"开始监听3000端口"``);` + k. d6 E+ S0 w; F X: P `});`
0 {9 k, K7 I/ G

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

$ v6 b2 N+ a4 X+ ?6 z' J- f9 g

访问localhost:3000的效果图;

; _4 s( E' t+ l: W
) }# K& d' ~6 F) _ d

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

% q% ^3 D" j E1 s3 B: j

2.ctx参数的使用demo

* f1 x5 f% u7 R% V
`const Koa = require(``"koa"``);` 5 w9 ~& f, R* K3 N `const koa =` `new` `Koa();` : x/ }. D( z# I4 e" K. u7 v `koa.use(async (ctx, next)=>{`. O% P8 n) y0 B9 S( W `ctx.body =` `"body可以返回数据,"``;` / u+ U* N5 Q- A0 \/ \7 ] `ctx.body +=` `"可以多次调用,"``;` 3 Q: X9 Z% ~3 }+ i `ctx.body +=` `"不需要end()"``;` / `: X) @. x3 G, f7 e- @ `});` + ]2 f* b6 {6 e7 a `koa.listen(3000, ()=>{` ( t/ G* J8 ~ v: H% M7 s `console.log(``"监听开始"``);`& c+ r- C3 _3 S0 x% @ `});`
9 j5 D9 }& O4 y" J: r% i

效果:

4 n+ Y/ |, T" S; D
: a( l5 W" [" E; O

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

. K' }5 C; l; o# q
`const Koa = require(``"koa"``);`& F' e# ?% h* E `const koa =` `new` `Koa();`; ?! N* @* e7 N5 N7 x7 h `koa.use(async (ctx, next)=>{`) F$ b. R& J+ W; O0 Y8 R9 D `ctx.body = ctx.url;` $ c( `, r# _) N. S6 C. P- p- Q `ctx.body = ctx.path;`3 u8 w& B' t" F0 Z9 _ `ctx.body = ctx.query;`2 s' ^( ^$ l) J( R# K `ctx.body = ctx.querystring;` . V3 r1 S, A l2 S! ` `});`) u% p. X6 Q5 S; Y N `koa.listen(3000, ()=>{`% ?0 h4 m- X0 c! X; k% r+ T `console.log(``"监听开始"``);` ; W W. b( K$ i4 [ `});`
% ?, w& L, U' o

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

6 ~/ i3 Y& `+ P! P0 M8 }* a

1. url: 整个路径

* { a. b8 f U; V; W
8 N# h* L5 g/ v& |

2. path: 非查询部分

; Y( p6 b8 D1 Q
0 j1 i& d8 u6 z" \

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

/ w! p1 a0 t% K ?+ Y0 t( m3 t
! D! V. G! g% P3 K* d7 _/ m0 v

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

3 n! [4 k$ Z: L; g8 u
1 B. l2 L+ }) `$ u2 W! [

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

9 x" S9 S- ~ d

2.简单爬虫练习

" n; Q8 }9 S [8 B$ _1 ^

安装request,cheerio模块

% ]" Q# A x+ I. G% e' _- S% i- n
`npm i -S request: 请求模块`3 H* S0 O* o# ^1 W/ U+ }8 u/ i# y `npm i -S cheerio: 抓取页面模块(JQ核心)`
* N `3 Y. S$ \' d% g6 }

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

- |; P+ k5 b. r% K' E+ r ^
`//导入模块`( i! x2 M; }; J7 |! D: c2 K. G. \ `const request = require(``"superagent"``);` `//导入请求模块`+ X) k( U' R$ x E3 `+ G4 V# ^ `const cheerio = require(``"cheerio"``);`8 j# t0 ~1 c. d' S( H% u `const {join} = require(``"path"``);`3 |; A8 _/ P2 |$ R, f `const fs = require(``"fs"``);` - O' u' V4 M: r, H0 X$ `+ \ `let arr = [],` `//存放数据`9 G8 n8 k0 w8 j. _, u `reg = /\n|\s+/g,` `//replace中使用` 8 R* S P5 ?" l0 `% S `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/)"``;` : R5 G: p8 h+ t" T; _8 d$ \ `request` ! }% `/ [# S9 W' e v6 r6 J `.get(url)`1 ^5 Z& i( h& }' ~0 [7 s" n `.end((err, res) => {` - A8 L' U+ M K `const $ = cheerio.load(res.text);` `//把字符串内的标签当成dom来使用`" I# o& L( l | `$(``".course-item"``).each((i, v) => {` 1 r0 M- H+ ^2 n `// v当前进来的dom,根据网页的布局结构来找到准确的dom节点`/ u3 x- F' }) G* ]0 }$ J2 n `const obj = {`; n. t$ q; b! J% B3 f `imgSrc : $(v).find(``"img"``).prop(``"src"``),` * |+ j& @+ Z4 S* ?% J/ P, W `price : $(v).find(``".fr span"``).text().replace(reg,` `""``),` V$ ]3 ~+ A: u. C& s2 x: [ `total : $(v).find(``".item-txt"``).text().replace(reg,` `""``),` * v" s9 ~! t& G0 ]% H2 p `href : join(url + $(v).find(``".cimg"``).prop(``"href"``))` ; d) h9 N1 Y7 i* D7 F+ F' v `};`) @3 J6 f# S, _% g `console.log(join(url + $(v).find(``".cimg"``).prop(``"href"``)));` `//拼接` 0 |8 ^: [$ z* H, ]' N `arr.push(obj);` `//把对象放进数组里` , b* U! b2 E4 V" Z; P& p9 x `});`% `+ S8 K" y6 R4 c- K3 _5 t3 V* | `fs.writeFile(``"./sjl.json"``, JSON.stringify(arr));` `//将爬到的数据写入文档中`3 s% |3 j, B3 `$ {0 @9 a `});`
9 i! E0 i8 w* a! c

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

8 G& W% W+ [2 ~5 z0 s9 p$ D8 H ; _3 ^ [) W$ p ! _4 p1 c5 j; c$ p8 k* ]" @5 S5 J& Z O2 A* |6 p & U1 B1 ~+ y; W" J: {" S
回复

举报 使用道具

相关帖子

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