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

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

掃碼體驗

在上一篇《實戰:在小程序中獲取用戶所在城市信息》中,介紹瞭如何獲取用戶所在城市,這一篇就介紹一下小程序雲函數開發的一些東西。前端

項目結構

小程序《看啥好呢》所有數據都來自豆瓣網和大麥網,整個項目結構以下node

整個項目結構

電影、電視模塊下的每一個分類,只是改變豆瓣網同一個接口某個字段便可,本地好看模塊是拿的大麥網的接口,而電影詳情頁是使用 Cherrio 實現豆瓣電影詳情頁網頁解析拿到的數據。git

項目目錄結構github

項目目錄結構

項目開發

因爲電影、電視列表模塊用的都是同一個接口,只是某些參數不一樣,而詳情頁是解析網頁方式,不是走的接口,因此處理邏輯與列表不相同,怎麼樣在一個雲函數中處理不一樣的邏輯呢。npm

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

router 模塊

在前端中,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 請求

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

全文完。


關注公衆號,第一時間接收最新文章。若是對你有一點點幫助,能夠點喜歡點贊點收藏,還能夠小額打賞做者,以鼓勵做者寫出更多更好的文章。

相關文章
相關標籤/搜索