實戰:小程式雲開發之雲函數開發

  • 2019 年 12 月 27 日
  • 筆記

最近在做自己的小程式《看啥好呢》,這個小程式是使用雲開發的方式開發的,功能特別簡單,就是獲取豆瓣、大麥網的數據展示,雖然功能簡單,但還是記錄下開發過程和一些技術點,大約會有兩篇博文產出,這是第二篇。GitHub地址

掃碼體驗

在上一篇《實戰:在小程式中獲取用戶所在城市資訊》中,介紹了如何獲取用戶所在城市,這一篇就介紹一下小程式雲函數開發的一些東西。

項目結構

小程式《看啥好呢》全部數據都來自豆瓣網和大麥網,整個項目結構如下

整個項目結構

電影、電視模組下的每個分類,只是改變豆瓣網同一個介面某個欄位即可,本地好看模組是拿的大麥網的介面,而電影詳情頁是使用 Cherrio 實現豆瓣電影詳情頁網頁解析拿到的數據。

項目目錄結構

項目目錄結構

項目開發

由於電影、電視列表模組用的都是同一個介面,只是某些參數不同,而詳情頁是解析網頁方式,不是走的介面,所以處理邏輯與列表不相同,怎麼樣在一個雲函數中處理不同的邏輯呢。

從上面的項目目錄結構可以看出,我為整個項目只劃分了兩個雲函數,分別是damai和douban,在damai中處理來自大麥網的數據,douban中處理來自豆瓣的數據。

Router模組

在前端中,Router 可以處理不同的請求分支,於是在雲函數中也可以使用 Router,下面使用了 tcb-router,它是一個基於 koa 風格的小程式·雲開發雲函數輕量級類路由庫,主要用於優化服務端函數處理邏輯。

douban/index.js

// 雲函數入口文件  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();  }

雲函數目錄結構如下

/douban  ----/node_modules  ----index.js  ----list.js  ----detail.js  ----package.json  

HTTP請求

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 是請求的路由,第二個參數開始即是請求需要的參數。

Cherrio實現詳情頁解析

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,是一個很好的學習項目。

【 全 文 完 】

本文代表個人觀點,內容僅供參考。若有不恰當之處,望不吝賜教!

本文鏈接:https://zhangbing.site/2019/12/09/實戰:小程式雲開發之雲函數開發/