微信小程序開發抽取HTML中數據的最快方法是正則表達式,而不是循環

做項目的過程中,剛好用到這個變量,因爲用微信小程序獲取了網頁源數據,但是是一堆HTML文檔代碼,若用循環來處理抽取裏面我想要的信息,太過於複雜,所以着手用正則表達式來做。

方法如下:

一、從網頁上獲取源數據(HTML文檔)

在js文件中,關鍵代碼如下:

Page({
  data: {
    csdn: {}//用於存儲獲取的html文檔
  },
 首先設置你想獲取信息的網址
 var url = 'https://blog.csdn.net'; 
 然後用 wx.request這個接口來訪問該網址,並獲取網頁源代碼
 wx.request({
      url: url,
      data: {
             },
      method: 'GET',//get是從服務器上獲取數據,post是向服務器傳送數據。瀏覽器用GET請求來獲取一個html頁面/圖片/css/js等資源;用POST來提交一個<form>表單,並得到一個結果的網頁          
      success: function (res) {
        that.setData({ csdn: res.data)});
      },
    })
    })
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

用這種方法得到的變量csdn值如下,由於數據量太大,只截取了部分代碼

ic/common/toolbar/js/m_toolbar-1.1.1.js" id="m-toolbar-tpl-scriptId" prod="blog"></script>
    <svg xmlns="http://www.w3.org/2000/svg" style="width:0; height:0; visibility:hidden; position: absolute;display: none"><defs><polygon id="SVGID_5_" points="41.8,34 41.8,56 38.2,56 38.2,34 28.5,43.2 24,43.2 40,28.1 56,43.2 51.5,43.2 			"/> </defs><symbol id="icon-close" viewBox="0 0 1024 1024">
    <path d="M896 0L512 384 128 0 0 128l384 384L0 896l128 128 384-384 384 384 128-128-384-384 384-384z" p-id="9079" fill="#cccccc"/>
  </symbol>
  <symbol id="icon-top" viewBox="0 0 80 80">
    <circle class="st0" cx="40" cy="40" r="40"/> <g> <g> <rect x="24" y="24" class="st1" width="32" height="3.5"/> </g> <g>  <use xlink:href="#SVGID_5_" style="overflow:visible;fill-rule:evenodd;clip-rule:evenodd;fill:#FFFFFF;"/> <clipPath id="SVGID_1_"> <use xlink:href="#SVGID_5_" style="overflow:visible;"/> </clipPath> </g> </g> 
  </symbol>
</svg>    <nav class="d-flex">
    <div class="nav-mask">
        <div class="warp">
                    <a class="btn-nav" onclick="changeNav($(this))" data-href="/" data-category="home">博客推薦</a>
                                                                        <a class="btn-nav" onclick="changeNav($(this))" data-href="/nav/watchers" data-category="watchers">動態</a>
                                        <a class="btn-nav" onclick="changeNav($(this))" data-href="/nav/career" data-category="career">程序人生</a>
                                        <a class="btn-nav" onclick="changeNav($(this))" data-href="/nav/python" data-category="python">Python</a>
                                        <a class="btn-nav" onclick="changeNav($(this))" data-href="/nav/java" data-category="java">Java</a>
                                        <a class="btn-nav" onclick="changeNav($(this))" data-href="/nav/ai" data-category="ai">百萬人學AI</a>
                                                                                                        <a class="btn-nav" onclick="changeNav($(this))" data-href="/nav/web" data-category="web">前端</a>
                                        <a class="btn-nav" onclick="changeNav($(this))" data-href="/nav/arch" data-category="arch">架構</a>
                                        <a class="btn-nav" onclick="changeNav($(this))" data-href="/nav/blockchain" data-category="blockchain">區塊鏈</a>
                                        <a class="btn-nav" onclick="changeNav($(this))" data-href="/nav/db" data-category="db">數據庫</a>
                                        <a class="btn-nav" onclick="changeNav($(this))" data-href="/nav/5g" data-category="5g">5G</a>
                                        <a class="btn-nav" onclick="changeNav($(this))" data-href="/nav/game" data-category="game">遊戲開發</a>
                                        <a class="btn-nav" onclick="changeNav($(this))" data-href="/nav/mobile" data-category="m
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

二、用正則表達式匹配想要的信息

1.什麼是正則表達式

說白了就是一種字符串匹配的模式,可以用來檢查一個串是否含有某種子串、將匹配的子串替換或者從某個串中取出符合某個條件的子串等。

2.正則表達式常用語法

(1)/表示正則表達式的開始與結束
(2)++號代表前面的字符必須至少出現一次(1次或多次)
例如:runoo+b,可以匹配 runoob、runooob、runoooooob 等。
(3)*表示字符可以不出現,也可以出現一次或者多次(0次、或1次、或多次)。
例如:runoo*b,可以匹配 runob、runoob、runoooooob 等,* 號代表
(4)? 問號代表前面的字符最多只可以出現一次(0次、或1次)
colou?r 可以匹配 color 或者 colour。
(5)\s匹配任何空白字符,包括空格、製表符、換頁符等等。
(6)\S匹配任何非空白字符。
(7)[標記一箇中括號表達式的開始。要匹配 [,請使用 \[。
(8)() 括號裏面是組, 可以提取組內的內容
(9)[\s\S]*?
是完全通配的意思;[ ]”是範圍描述符。 \s是指空白,包括空格、換行、tab縮進等所有的空白,而\S剛好相反,這樣一正一反下來,就表示所有的字符,完全的,一字不漏的。 例如:
<span id="ctext">([\s\S]*?)</span> 意思就是匹配所有在兩個<span>中間有0個或多個任意字符的字符串. 並把內容部分生成個組
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

更多的語法可以查詢菜鳥教程https://www.runoob.com/regexp/regexp-syntax.html

3.寫出正則表達式

下面列舉出我在項目中常用到的一種

    let my_reg =/<td class='colorize'>([\s\S]*?)<\/td>/gmi;
  • 1
  • 2

這是抓取網頁HTML信息種最常用的一種寫法,直接用標籤+全匹配,
則下面這句HTML標籤內容中的“被抓內容”就會被匹配出來。

...
<td class='colorize'>被抓內容</td> 
...
  • 1
  • 2
  • 3

後面的參數如下

  • g表示匹配儘可能多
  • i: 忽略大小寫
  • 參數m表明可以進行多行匹配,但是這個只有當使用^和$模式時纔會起作用,在其他的模式中,加不加入m都可以進行多行匹配(其實說多行的字符串也是一個普通字符串)

4.抽取數據------.exec()函數

在微信小程序中通過以下**.exec()函數**進行匹配,將結果放入數組

data_we_want = my_reg.exec(page)
  • 1

關於返回值數組data_we_want :

  • 此數組的第 0 個元素是與正則表達式相匹配的文本
  • 第 1 個元素是與 RegExpObject 的第 1 個子表達式相匹配的文本(如果有的話)
  • 第 2 個元素是與 RegExpObject 的第 2 個子表達式相匹配的文本(如果有的話),以此類推

除了數組元素和 length 屬性之外,exec() 方法還返回兩個屬性:

  • index 屬性聲明的是匹配文本的第一個字符的位置。
  • input 屬性則存放的是被檢索的字符串 string。

5.全局循環抽取

用這種方面你會發現,雖然配置了全局匹配,也就是加了參數gmi,但是有可能只匹配了一次,也就是返回值數組中只有一個元素,後續就不匹配了,原因是還要再加循環才行。方法如下:

  var data=[];  
  while ((tmp_reg =  my_reg.exec(page)) != null) {      
      data.push(util.regular(tmp_reg[1]));     
      }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

這種方法會將page頁面中的所有元素匹配一遍,但有時你會發現第一個元素老是匹配不到,這是因爲.lastIndex 參數剛開始不爲零。

這個參數代表以爲指針位置,每次都從這個位置開始匹配,所以剛開始需要清零。

優化後,代碼如下:

  var data=[];  
  my_reg.lastIndex = 0;   
  while ((tmp_reg =  my_reg.exec(page)) != null) {      
      data.push(util.regular(tmp_reg[1]));     
      }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

在while循環內部lastIndex 並沒有清零,所以每循環一次拿出一個匹配數組,我們只要第1個元素tmp_reg[1],這是我們匹配到的文本,然後下一次循環匹配會按照lastIndex的位置繼續往後匹配。

三、幾種常用正則表達式示例

var names = /^[\u4E00-\u9FA5A-Za-z]+$/; //姓名
var phonetel = /^(((13[0-9]{1})|(15[0-9]{1})|(18[0-9]{1})|(17[0-9]{1}))+\d{8})$/; //手機號
var emailnums = /^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+(.[a-zA-Z0-9-]+)*.[a-zA-Z0-9]{2,6}$/; //郵箱
var idCard = /(\d{15}$)|(^\d{18}$)|(\d{17}(\d|X|x)$)/; //身份證
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章