基於小程序開發的藏書館

一、小程序的發展

jsbridge -> js-sdk -> 小程序html

  • 騰訊內部使用的jsbridge,被外部發現,並使用,逐漸成爲微信中網頁的事實標準。後提供了外部使用的js-sdk,以後爲了提供更豐富的能力,提供小程序。
  • 小程序中js的組成:
    小程序的邏輯層和渲染層是分開的,邏輯層運行在 JSCore 中,並無一個完整瀏覽器對象,於是缺乏相關的DOM API和BOM API。

二、後端技術

後端可經過微信提供的雲服務和本身搭建服務端來實現,二者的區別以下:
真棒 真棒node

能夠看到,使用本身搭建的服務端,須要必定的運維能力,須要提供數據庫、https接口等,成本比較大。對於我的開發者,或者沒有相關服務器、運維能力的團隊,可使用雲服務。jquery

三、雲開發的流程

在下面的demo事例中,將提供相應雲開發具體操做方式。
真棒mongodb

四、藏書館demo體驗

demo功能說明:數據庫

提供了書本的掃碼、查詢錄入功能,將家中的圖書管理起來。其中因爲豆瓣的書本查詢api關閉,最終經過網頁爬蟲,實如今線書本信息收集的工做。經過將書本信息存入提取,錄入到數據庫中,造成本身的在線書庫。npm

功能部分:json

  • 一、微信掃碼識別條形碼 or 手動輸入做者、書名、isbn查詢
  • 二、亞馬遜網頁爬蟲
  • 三、數據錄入數據庫中

本示例提供了兩種服務端,nodejs + mongodb自建;及雲服務。將提供二者的實現方法。網頁爬蟲

上截圖:小程序

真棒 真棒

4.一、微信掃碼識別條形碼

wx.scanCode({
  success (res) {
    that.searchBookList(res.result);
  },
  fail(err) {
    console.log('fail', err);
  }
});

微信提供條形碼識別的api,直接調用便可~~生成之後,經過亞馬遜網頁爬蟲爬取信息。後端

4.二、亞馬遜網頁爬蟲

因爲豆瓣的圖書api禁用,只能經過網頁爬蟲的方式去獲取相關的信息,對比了豆瓣、噹噹、京東、亞馬遜、幾個在線圖書館,最終選擇了亞馬遜。區別對比:

真棒

從對比表格能夠看出,僅僅亞馬遜能夠做爲圖書信息收集的渠道,但也會出現不穩定的狀況,有時候須要屢次請求才可取到。豆瓣作了相應的規避爬蟲的處理,書本信息沒法讀取到(爬了幾回,ip被豆瓣放入了黑名單。。。)。噹噹、京東比較尷尬的點是,它的查詢結果包含其餘第三方書店的結果信息,致使一個isbn對應不少的結果記錄,在後面作做者、書名的查詢擴展時,比較難過濾,因此丟棄。在線圖書館狀況就更多,信息雜亂,書目不全等,丟棄。綜合以上,最終選用亞馬遜網頁來實現書本信息的收集。

包含兩個爬蟲:

  • 一、根據做者、書名、isbn查詢書目列表;
  • 二、step1 裏的亞馬遜詳情連接,跳轉到詳情頁,讀取具體書本詳細信息。

step1: 搜索結果爬蟲

// 須要使用encodeURI進行編碼,處理中文問題
const bookInfoDomain = 'https://www.amazon.cn';
rp(bookInfoDomain + '/s?k=' + encodeURI(event.params.searchValue + '&i=stripbooks')).then(html => {
    return getBookBaseInfo(html);
}).catch(err => {
    console.log(err)
});

書本查詢結果列表的搜索結果,(搜索書名「自立」的結果)如圖所示:
真棒 真棒

左邊爲亞馬遜的圖書列表,其中紅線框中的信息爲須要提取的圖書信息;右邊爲提取相關信息後,在小程序端展示的搜索結果列表。
經過分析結果頁的dom結構,來提取相關信息,代碼:

let bookHtmlList = [];
if (htmlString) {
    let $ = cheerio.load(htmlString);
    $('.s-search-results .s-result-item').each((i, e) => {
        let href = $(e).find("[data-component-type='s-product-image'] a").attr('href');
        let logo = $(e).find(".s-image").attr('src');
        let name = $(e).find("h2").text();
        let price = ($(e).find(".a-spacing-top-small .a-offscreen").text() || '').replace(/[^0-9|\.]/ig,"");
  
        bookHtmlList.push({......}); // 省略
    })
}
return bookHtmlList;

使用cheerio來解析html串,其使用jquery的核心實現,可在服務端,直接像jquery同樣使用。在列表頁提取了href,爲書本詳情頁的跳轉作準備。

step2:詳情頁爬蟲

書本詳情的結果如圖所示:

真棒 真棒

左圖爲亞馬遜的圖書列表,右圖爲小程序收集到相關信息的展現頁:

總結:爬蟲的重點爲 找到核心、有效信息的網頁,再使用cheerio進行解析,最後按照須要,使用類jquery api提取信息便可。

4.三、數據錄入數據庫中

這裏提供了兩種服務提供方式:

  • a、本地nodejs + mongodb
  • b、小程序自帶雲服務
本地nodejs + mongodb

真棒

如上圖,爲nodejs + mongodb的服務端代碼結構,經過提供api的方式,提供數據服務。固然,上線以後,須要提供ssh證書,僅https協議的訪問才被容許;在小程序的配置當中,須要將相關的服務域名進行配置(另外,小程序沒有cookie、session的機制,若是服務端是作遷移的,須要在這方面作下融合)。

小程序自帶雲服務

雲服務的部署、運維,如今就看看具體如何操做:

  • step1:生成雲開發的帳號,經過小程序的devtools,點擊"雲開發"去生成,以下圖所示;
    真棒

  • step2:建立雲開發目錄,通常與小程序項目同級;

  • step3:新建雲函數,在生成的雲函數目錄內(該目錄爲雲函數的名稱),進行npm install,安裝相關的組件;(小程序經過雲函數,與雲服務進行交互)
    真棒

  • step4:進行相關雲開發的配置,配置方法以下:

    a、project.config.json裏添加:

    {"cloudfunctionRoot": "cloudfunctions/",}

    b、app.js的配置

    // 進行雲服務的初始化
    onLaunch: function () {
        if (!wx.cloud) {
            console.error('請使用 2.2.3 或以上的基礎庫以使用雲能力')
        } else {
            wx.cloud.init({
                traceUser: true,
            })
        }
        ......
    }
  • step5: 雲函數使用

    a、調用雲函數

    // 亞馬遜查找相應的書本
    wx.cloud.callFunction({
        name: 'bookinfo',
        data: {
            type: 'search',
            params: {
                searchValue
            }
        },
        success: data => {
            ......
        },
        fail: err => {
        ......
        }
    })

    b、雲函數接收

    // 雲函數入口函數
        exports.main = async (event, context) => {
            ......
            return rst;
        }

    其中event的屬性與data同樣,可經過event,使用data中傳遞的值信息。

  • step6: 數據庫的使用

    const bookStoreDb = cloud.database();
        const bookCollection = bookStoreDb.collection('book');
        const _ = bookStoreDb.command
        let whereInfo = {};
      if (event.params.searchValue) {
        whereInfo = _.or([
          {
            author: {$regex: '.*'+ event.params.searchValue}
          },
          {
            isbn: {$regex: '.*'+ event.params.searchValue}
          },
          {
            name: {$regex: '.*'+ event.params.searchValue}
          },
        ])
      }
    
      // 一次最多查詢100個記錄,total大於100,須要屢次請求,拼合
      rst = await bookCollection.where(whereInfo).get().then(res => {
        ......
      });
      return rst;

五、其餘

相關文章
相關標籤/搜索