最近在作本身的小程序《看啥好呢》,這個小程序是使用雲開發的方式開發的,功能特別簡單,就是獲取豆瓣、大麥網的數據展現,雖然功能簡單,但仍是記錄下開發過程和一些技術點,大約會有兩篇博文產出,這是第二篇。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,是一個很好的學習項目。
全文完。
關注公衆號,第一時間接收最新文章。若是對你有一點點幫助,能夠點喜歡點贊點收藏,還能夠小額打賞做者,以鼓勵做者寫出更多更好的文章。