微信小程序實現博客園文章閱讀功能


在微信小程序開發中,我們可以根據不同的業務場景,開發不同的業務應用,可以基於自身域名服務接口,也可以基於第三方的域名接口進行處理(如果被禁用除外),本篇隨筆介紹使用小程序來實現我博客(http://wuhuacong.cnblogs.com)的文章閱讀功能,這個小程序主要用來介紹使用介紹基於Javascript的正則表達式的處理應用,和常規在C#里面使用正則表達式有一些差異,因此可以作為后續使用正則表達式處理業務數據的一個練兵吧。

1、Request接口合法域名配置

一般情況下,我們知道微信的Request請求是需要配置合法的域名的,這種安全性可以是微信攔截有潛在危險的或者不喜歡的域名接口,Request合法域名配置界面如下所示。

一般情況下,我們在上面增加合法域名即可,這樣小程序發布后,就可以順利通過檢查並獲取數據了,本篇隨筆由於想讀取博客園個人博客園的文章,因此需要配置博客園的域名,不過很不幸,博客園的域名上了黑名單被禁用了。

如果我們在開發環境,我們可以通過不包含對合法域名的檢驗處理,不過在開發環境必須取消勾選“不校驗”。

 

2、小程序功能設計

首先我們來看看主體界面的效果圖,然后在進行分析具體的功能實現,具體界面效果如下所示。

博客文章列表內容如下所示:

文章詳細界面效果如下所示:

這些文章直接都是從博客園頁面中獲取,並通過Javascript的正則表達式進行提取,然后展示在小程序上的,對於HTML內容的展示我們還是使用了WxParse的這個HTML解析組件,具體功能和使用過程可以參考我之前的隨筆《在微信小程序中使用富文本轉化插件wxParse 》進行詳細了解。對於Javascript函數的封裝,我們還是使用比較方便的Promise進行封裝處理,具體知識可以參考我隨筆《在微信小程序的JS腳本中使用Promise來優化函數處理 》進行詳細了解。

一般我們也准備把公用方法提取出來,放到工具類Utils/util.js里面,配置統一放到utils/config.js里面,這樣方便小程序的模塊化處理。

項目的文件目錄如下所示。

在Utils/util.js里面,我們封裝了wx.request的獲取內容方法如下所示。

//封裝Request請求方法
function request(url,method,data = {},type='application/json'){
  wx.showNavigationBarLoading();
  
  return new Promise((resove,reject) => {
    wx.request({
      url: url,
      data: data,
      header: {'Content-Type': type},
      method: method.toUpperCase(), // OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT
      success: function(res){
        wx.hideNavigationBarLoading()
        resove(res.data)
      },
      fail: function(msg) {
        console.log('reqest error',msg)
        wx.hideNavigationBarLoading()
        reject('fail')
      }
    })
  })
}

而在Config.js里面,我們主要定義好一些常用的參數,如URL等

在列表頁面,我們主要是展示文字標題和日期等信息,而列表是需要滾動翻頁的,因此我們使用微信界面組件 scroll-view 來展示,具體界面代碼如下所示。

<block wx:if="{{showLoading}}">
    <view class="loading">玩命加載中…</view>
</block>
<block wx:else>
    <scroll-view scroll-y="true" style="height: {{windowHeight}}rpx" scroll-top="{{scrollTop}}" bindscroll="scroll" bindscrolltolower="scrolltolower">
        <view class="blog">
            <block wx:for="{{blogs}}" wx:for-index="blogIndex" wx:for-item="blogItem" wx:key="blog">
                <view data-id="{{blogItem.id}}" catchtap="viewBlogDetail" class="flex box box-lr item">
                  <view class="flex item_left">
                    <view><text class="title">{{blogItem.title}}</text></view>
                    <view><text class="sub_title">{{blogItem.date}}</text></view>
                  </view>
                </view> 
            </block>
            <block wx:if="{{hasMore}}">
                <view class="loading-tip">拼命加載中…</view>
            </block>
            <block wx:else>
                <view class="loading-tip">沒有更多內容了</view>
            </block>
        </view>
    </scroll-view>
</block>

通過綁定向下滑動的事件 bindscrolltolower="scrolltolower" 我們可以實現列表內容的滾動刷新。

我們通過前面介紹的封裝Request方法,可以獲取到HTML內容,如下函數所示。

  //獲取博客文章列表
  getList:function(start =1) {
      return new Promise((resolve, reject) => {
        var that = this;
        var data = {};
        var type = "text/html";
        var url = config.mainblog_url + start;
        
        if (that.data.hasMore) {
          app.utils.get(url, data, type).then(res => {

通過指定type = "text/html",並且傳入對應的起始位置,可以獲取到對應頁面的內容。

在博客園里面,【我的隨筆】里面的標准URL地址為:http://www.cnblogs.com/wuhuacong/p/?page=n,其中 n 是當前的頁碼。

頁面上的頁碼效果如下所示:

分析頁面源碼,可以看到頁碼標簽的源碼如下所示。

因此我們對HTML源碼進行正則表達式的匹配即可獲取對應的內容(關鍵是獲取多少頁,為后面循環獲取文章列表做准備)。

關於正則表達式的測試,建議使用RegExBuilder(http://www.jb51.net/softs/389196.html)進行測試,其實我之前傾向於使用The Regulator 2.0這個很好的程序測試正則表達式,不過這個軟件經常性的不能啟動使用。

不過后來測試使用RegExBuilder,也覺得非常不錯,其中勾選ECMAScript是為了我們在Javascript使用正則表達式的選項,畢竟和在C#里面使用正則標識還是有一些差異,如不支持單行選擇,以及一些微小差異。

對於在Javascript中使用正則標識,建議大家溫習下下面幾篇隨筆,有所幫助:

深入淺出的javascript的正則表達式學習教程

使用javascript正則表達式實現遍歷html字符串

 《JavaScript之正則表達式

 以及一個常見的坑,在HTML內容匹配的時候,不支持.*這種很普通的模式,這種由於不能選擇單行模式導致的,變通的方式是使用[\s\S]來實現匹配所有字符處理。

可以參考文章:https://stackoverflow.com/questions/1068280/javascript-regex-multiline-flag-doesnt-work 了解下。

另外對於Javascript的正則書寫,經常看到i,g,m的結束符

修飾符   描述
i (ignore case)
執行對大小寫不敏感的匹配。
g (global search)
執行全局匹配(查找所有匹配而非在找到第一個匹配后停止)。
m (multiline)
執行多行匹配。

它的意思你參考文章了解:

https://zhidao.baidu.com/question/620656820875333772.html

Javascript的正則匹配處理,支持正則表達式的String對象的方法可以使用search()方法、match()方法、replace()方法、split()方法、

RegExp對象方法包括:test()方法、exec()方法。

具體Javascript的正則表達式使用,可以好好學習下《深入淺出的javascript的正則表達式學習教程》,就很清晰了。

例如對於我們這篇小程序,我們獲取頁碼的js代碼如下所示。

  var reg = /共(\d{0,})頁/g;
  var pageNum = reg.exec(html)[1];
  //console.log(pageNum);

  that.setData({
    end:pageNum, //設置最大頁碼
  });

 

在獲取每篇隨筆文章的標題、URL、日期等信息,我編寫了一個正則表達式來匹配,如下所示。

var regContent=/class=\"postTitl2\">.*?href=\"(.*?)\">(.*?)<\/a>.*?class=\"postDesc2\">(.*?)\s*閱讀:.*?<\/div>/igm;

正則表達式的內容,在使用前,一定需要在這個工具上測試,測試通過了我們再在代碼上使用,減少調試錯誤的時間。

下面的測試結果如下所示。

獲取文章列表信息的小程序js代碼如下所示。

在之前介紹的列表展示界面代碼里面,我們綁定了單擊連接的事件,如下界面所示標注所示。

這個事件就是觸發導航到詳細界面,如下所示,我們把URL作為id傳入到詳細的界面里面。

  viewBlogDetail: function(e) {
    var data = e.currentTarget.dataset;
    var url = data.id;
    // console.log(url);
    wx.navigateTo({
      url: "../details/details?id=" + data.id
    })
  },

在文章詳細界面展示里面,界面的代碼如下所示。

<import src="../../utils/wxParse/wxParse.wxml" />
<view class="flex box box-lr item">
    <view class="flex item_left">
        <view>
            <text class="title">{{detail.title}}</text>
        </view>
    </view>
</view>
<view class="page">
    <view class="page__bd">
        <view class="weui-article">
            <view class="weui-article__p">
                <template is="wxParse" data="{{wxParseData:article.nodes}}"/>
             </view>
        </view>
    </view>
</view>

這里引入了WxParse作為HTML內容解析的組件,我們在頁面代碼頂部引入組件代碼

<import src="../../utils/wxParse/wxParse.wxml" />

具體處理的內容在JS代碼里面,我們的JS代碼如下所示。

  //獲取文章詳細內容
  getDetail(url) {    
    var that = this;
    var type = "text/html";
    app.utils.get(url, {}, type).then(res => { 
        // console.log(res);
        var html = res;
        var regContent = /id=\"cb_post_title_url\".*?>([\s\S]*?)<\/a>[\s\S]*?id=\"cnblogs_post_body\">([\s\S]*?)<\/div><div\s*id=\"MySignature\">/igm
        var matchArr;
        if ((matchArr = regContent.exec(html))) {
            var detail = {
              id: url,
              title : matchArr[1],   //titile
              content : matchArr[2],  //content
            };

            that.setData({
              detail:detail
            });
            WxParse.wxParse('article', 'html', detail.content, that, 5);              
        };
    });
  },

 其中的Javascript的正則表達式如下:

var regContent = /id=\"cb_post_title_url\".*?>([\s\S]*?)<\/a>[\s\S]*?id=\"cnblogs_post_body\">([\s\S]*?)<\/div><div\s*id=\"MySignature\">/igm

我們在工具上測試,得到相關的效果后再在代碼上使用。

最后就可以獲得詳細的展示效果了,文章詳細界面效果如下所示:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM