最近在作本身的小程序《看啥好呢》,这个小程序是使用云开发的方式开发的,功能特别简单,就是获取豆瓣、大麦网的数据展现,虽然功能简单,但仍是记录下开发过程和一些技术点,大约会有两篇博文产出,这是第二篇。GitHub地址 html
在上一篇《实战:在小程序中获取用户所在城市信息》中,介绍了如何获取用户所在城市,这一篇就介绍一下小程序云函数开发的一些东西。前端
小程序《看啥好呢》所有数据都来自豆瓣网和大麦网,整个项目结构以下node
电影、电视模块下的每一个分类,只是改变豆瓣网同一个接口某个字段便可,本地好看模块是拿的大麦网的接口,而电影详情页是使用 Cherrio 实现豆瓣电影详情页网页解析拿到的数据。git
项目目录结构github
因为电影、电视列表模块用的都是同一个接口,只是某些参数不一样,而详情页是解析网页方式,不是走的接口,因此处理逻辑与列表不相同,怎么样在一个云函数中处理不一样的逻辑呢。npm
从上面的项目目录结构能够看出,我为整个项目只划分了两个云函数,分别是damai和douban,在damai中处理来自大麦网的数据,douban中处理来自豆瓣的数据。json
在前端中,Router 能够处理不一样的请求分支,因而在云函数中也可使用 Router,下面使用了tcb-router,它是一个基于 koa 风格的小程序·云开发云函数轻量级类路由库,主要用于优化服务端函数处理逻辑。小程序
douban/index.jssegmentfault
// 云函数入口文件 const cloud = require('wx-server-sdk') const TcbRouter = require('tcb-router') cloud.init() // 云函数入口函数 exports.main = async (event, context) => { const app = new TcbRouter({ event }) /** 查询列表 */ app.router('list', async (ctx, next) => { const list = require('./list.js') ctx.body = list.main(event, context) }) /** 查询详情 */ app.router('detail', async (ctx, next) => { const detail = require('./detail.js') ctx.body = detail.main(event, context) }) return app.serve(); }
云函数目录结构以下promise
/douban ----/node_modules ----index.js ----list.js ----detail.js ----package.json
HTTP请求方面,小程序云函数中经常使用的是request-promise,它是一个 Promise 分格的HTTP请求库,使用它还必须安装它的依赖,两个包都要安装
npm install --save request npm install --save request-promise
下面看看电影列表是怎么处理的,douban/list.js
const rp = require('request-promise') exports.main = async (event, context) => { const type = event.type const tag = encodeURI(event.tag) const limit = event.limit || 50 const start = event.start || 0 const options = { uri: \`https://movie.douban.com/j/search\_subjects?type=${type}&tag=${tag}&page\_limit=${limit}&page\_start=${start}\`, headers: { 'Host': 'movie.douban.com', 'Referer': 'https://movie.douban.com/' }, json: true } return rp(options).then(res => res).catch(err => { console.log(err) }) }
请求参数都放在 event 当中,在调用云函数的时候传递,下面是电影列表页面调用云函数的代码
let {id, type} = this.data wx.cloud.callFunction({ name: 'douban', data: { $url: 'list', type, tag: id == 'hot' ? '热门' : '最新' } }).then(res => { const result = res.result this.setData({ dataList: result.subjects }, () => { wx.hideLoading() }) }).catch(err => { console.log(err) wx.showToast({ title: '出错了', icon: 'none' }) wx.hideLoading() })
从调用云函数的 data 属性中的第一个参数$url
是请求的路由,第二个参数开始便是请求须要的参数。
cheerio是一个 jQuery Core 的子集,其实现了 jQuery Core 中浏览器无关的 DOM 操做 API,如下是一个简单的示例:
var cheerio = require('cheerio'); // 经过 load 方法把 HTML 代码转换成一个 jQuery 对象 var $ = cheerio.load('<h2 class="title">Hello world</h2>'); // 可使用与 jQuery 同样的语法来操做 $('h2.title').text('Hello there!'); $('h2').addClass('welcome'); console.log($.html()); // 将输出 <h2 class="title welcome">Hello there!</h2>
简单来讲,cheerio 就是服务器端的 jQuery,去掉了 jQuery 的一些效果类和请求类等等功能后,仅保留核心对 dom 操做的部分,所以可以对 dom 进行和 jQuery 同样方便的操做。它是咱们筛选数据的利器——把多余的 html 标签去掉,只留下咱们想要的内容的重要工具。须要注意的是,cheerio 并不支持全部 jQuery 的查询语法,好比$('a:first')
会报错 ,只能写成$('a').first()
,在使用的时候须要注意。
下面是电影、电视的详情页处理逻辑
const rp = require('request-promise') const cheerio = require('cheerio') exports.main = async (event, context) => { const subjectId = event.id const baseUrl = 'https://movie.douban.com/j' const options = { uri: \`${baseUrl}/subject\_abstract?subject\_id=${subjectId}\`, headers: { 'Host': 'movie.douban.com', 'Referer': 'https://movie.douban.com/' }, json: true } return rp(options).then((res) => { return rp(\`https://movie.douban.com/subject/${subjectId}/\`) .then((html) => { const $ = cheerio.load(html) const plot = $('#link-report').find('span').text(); //.replace(/\\s/g, '') res.subject.plot = plot return res }).catch((err) => { console.log(err) }); }).catch((err) => { console.log(err) }); }
完整源码已开源GitHub,是一个很好的学习项目。
全文完。
关注公众号,第一时间接收最新文章。若是对你有一点点帮助,能够点喜欢点赞点收藏,还能够小额打赏做者,以鼓励做者写出更多更好的文章。