關於寫作那些事之利用 js 統計各大部落格閱讀量

雪之夢技術驛站發表於2019-04-13

在日常文章資料統計的過程中,純手動方式已經難以應付,於是乎,逐步開始了程式介入方式進行統計.

在上一節中,探索利用 csv 檔案格式進行文章資料統計,本來以為能夠應付一陣子,沒想到僅僅一天我就放棄了.

原因還不是因為我懶,需要複製文章內容,然後整理成特定的 csv 格式,最後利用已編寫的 java 工具類進行統計.

在這三步操作中,第一步複製文章內容最簡單,第二步整理文章格式最麻煩,第三步編寫 csv 工具類最技術.

因此,能不能再簡單點?懶癌晚期,必須繼續尋求新的解決方案.

關於如何利用 csv 檔案處理統計資料,可以參考 snowdreams1006.github.io/static-semi…

實現效果

慕課手記

慕課手記 : www.imooc.com/u/5224488/a…

慕課手記

簡書

簡書 : www.jianshu.com/u/577b0d76a…

簡書

部落格園

部落格園 : www.cnblogs.com/snowdreams1…

簡書

騰訊雲社群

騰訊雲社群 : cloud.tencent.com/developer/u…

騰訊雲社群

js 抓取分析資料

下面以 chrome 瀏覽器為例,說明如何利用預設控制檯抓取關鍵資料,本文需要一定的 jQuery 基礎.

慕課手記

在目標頁面右鍵選擇檢查選項,開啟預設開發者控制檯,點選最左側的小滑鼠箭頭,然後選中關鍵資料,比如瀏覽量.

此時,開發者控制檯自動滾動到元素(Elements)選項卡,在目標資料上右鍵點選複製(Copy),接著點選複製選擇器(Copy selector),現在已經定位到閱讀量的節點.

imooc-copy-selector.png

點選控制檯(Console)選項卡,並且將選擇器更改成 jQuery 選擇器,即$("複製的選擇器").text(),現在在控制檯直接輸出內容,看一下能否抓取到瀏覽量吧!

imooc-paste-jQuery-selector.png

現在已經成功定位到指定元素,而我們要統計的是全部文章的閱讀量,因此需要定位到全部元素.

$("#articlesList > div:nth-child(1) > div.item-btm.clearfix > div > div:nth-child(1) > em").text();
複製程式碼

簡單分析下文章結構結合選擇器分析,可以得知, 瀏覽,推薦和評論三者文件基本一致,唯一不同之處就是排列順序而已,因此想要準確定位到瀏覽數,需要定位到第一個元素,推薦量則是第二個元素,因此類推.

<div class="r right-info">
    <div class="favorite l">
        <i class="icon sns-thumb-up-outline"></i><em> 83瀏覽</em>
    </div>
    <div class="favorite l">
        <i class="icon sns-thumb-up-outline"></i><em> 1推薦</em>
    </div>
    <div class=" l">
        <i class="icon sns-comment"></i><em> 0評論</em>
    </div>    
</div>
複製程式碼

弄清楚基本文件結構後,開始著手改造選擇器使其定位到全部文章的瀏覽量,我們做如下改造.

$("#articlesList div:nth-child(1) > em").text();
複製程式碼

僅僅保留頭部和尾部,再去掉中間部分 > div:nth-child(1) > div.item-btm.clearfix > div > ,這樣就輕鬆定位到全部元素的瀏覽量了,是不是很簡單?

imooc-modify-jQuery-selector.png

看到控制檯輸出結果,心裡瞬間踏實了,這不剛好是第一頁全部文章的瀏覽量嗎?觀察輸出內容格式可知,我們需要將整個字串按照空格分割成字串陣列.

需要注意的是,行首還有一個空格喲,因此在分割成字串陣列前,我們先將行首的空格去除掉.

// 去除空格前:" 83瀏覽 91瀏覽 114瀏覽 150瀏覽 129瀏覽 175瀏覽 222瀏覽 173瀏覽 225瀏覽 200瀏覽 201瀏覽 217瀏覽 291瀏覽 202瀏覽 229瀏覽 184瀏覽 226瀏覽 155瀏覽 153瀏覽 211瀏覽"

$("#articlesList div:nth-child(1) > em").text().trim();

// 去除空格後: "83瀏覽 91瀏覽 114瀏覽 150瀏覽 129瀏覽 175瀏覽 222瀏覽 173瀏覽 225瀏覽 200瀏覽 201瀏覽 217瀏覽 291瀏覽 202瀏覽 229瀏覽 184瀏覽 226瀏覽 155瀏覽 153瀏覽 211瀏覽"
複製程式碼

現在我們再將這整個字串按照空格分割成字串陣列.

// 分割字串前: "83瀏覽 91瀏覽 114瀏覽 150瀏覽 129瀏覽 175瀏覽 222瀏覽 173瀏覽 225瀏覽 200瀏覽 201瀏覽 217瀏覽 291瀏覽 202瀏覽 229瀏覽 184瀏覽 226瀏覽 155瀏覽 153瀏覽 211瀏覽"

$("#articlesList div:nth-child(1) > em").text().trim().split(" ");

// 分割字串後: ["83瀏覽", "91瀏覽", "114瀏覽", "150瀏覽", "129瀏覽", "175瀏覽", "222瀏覽", "173瀏覽", "225瀏覽", "200瀏覽", "201瀏覽", "217瀏覽", "291瀏覽", "202瀏覽", "229瀏覽", "184瀏覽", "226瀏覽", "155瀏覽", "153瀏覽", "211瀏覽"]
複製程式碼

現在我們已經夠將整個字串分割成一個個小的字串,下面需要再將83瀏覽中的瀏覽去掉,僅僅保留數字83.

$.each($("#articlesList div:nth-child(1) > em").text().trim().split(" "),function(idx,ele){
     console.log(ele.substr(0,ele.lastIndexOf("瀏覽")));
});
複製程式碼

imooc-split-ele-read.png

現在我們已經抓取到真正的瀏覽量,接下來就比較簡單了,直接將這些瀏覽量進行累加即可,需要注意的是,這裡的瀏覽數還是字串型別,需要轉換成數字型別才能進行累加運算喲!

//閱讀量
var readCount = 0;
$.each($("#articlesList div:nth-child(1) > em").text().trim().split(" "),function(idx,ele){
     readCount += parseInt(ele.substr(0,ele.lastIndexOf("瀏覽")));
});
console.log("閱讀量: " + readCount);
複製程式碼

imooc-read-count.png

小結

我們以 chrome 瀏覽器為例,講解了如何利用自帶的控制檯工具抓取關鍵資料,從頁面結構分析入口,一步一個腳印提取有效資料,最終從一條資料變成多條資料,進而實現資料的累加統計.

總體來說,還是比較簡單的,並不需要太多的基礎知識,但還是稍微總結其中涉及到的 jQuery 知識點吧!

  • 定位到具體元素: $("這裡是複製的選擇器")
  • 定位到具體元素內容: $("這裡是複製的選擇器").text()
  • 去除字串首尾空格: $("這裡是複製的選擇器").text().trim()
  • 將字串按照空格分割成字串陣列: $("這裡是複製的選擇器").text().trim().split(" ")
  • 擷取字串指定部分: ele.substr(0,ele.lastIndexOf("瀏覽")
  • 將字串轉化成數字型別: parseInt(ele.substr(0,ele.lastIndexOf("瀏覽")));
  • 變數累加求和: readCount += parseInt(ele.substr(0,ele.lastIndexOf("瀏覽")));

完整示例:

//閱讀量
var readCount = 0;
$.each($("#articlesList div:nth-child(1) > em").text().trim().split(" "),function(idx,ele){
     readCount += parseInt(ele.substr(0,ele.lastIndexOf("瀏覽")));
});
console.log("閱讀量: " + readCount);

//推薦量
var recommendCount = 0;
$.each($("#articlesList div:nth-child(2) > em").text().trim().split(" "),function(idx,ele){
     recommendCount += parseInt(ele.substr(0,ele.lastIndexOf("推薦")));
});
console.log("推薦量: " + recommendCount);

//評論量
var commendCount = 0;
$.each($("#articlesList div:nth-child(3) > em").text().trim().split(" "),function(idx,ele){
     commendCount += parseInt(ele.substr(0,ele.lastIndexOf("評論")));
});
console.log("評論量: " + commendCount);
複製程式碼

簡書

簡書的文章資料不一定很規整,比如有的釋出文章還沒有簡書鑽,所以閱讀量的排列順序就是不確定的,這一點不像前面介紹的慕課手記,但是簡書的關鍵資料前面是有小圖示的,因此我們可以利用圖示定位到旁邊的資料.

jianshu-selector-analysis.png

按照前面介紹的步驟,我們仍然定位到閱讀量,然而 #note-44847909 > div > div > a:nth-child(2) > i 卻不能直接使用,因為我們剛剛分析了,簡書不能利用順序定位只能用圖示輔助定位.

所以,還是先看看文件結構,嘗試著直接定位到全部的閱讀量小圖示.

jianshu-locate-icon.png

經過分析文章結構,我們可以很輕鬆定位到全部閱讀小圖示,當然這是一個元素陣列,並不是字串陣列喲!

$("#list-container .ic-list-read")
複製程式碼

接下來我們看一下能否正確定位到每一個小圖示,進而定位到小圖示左側的閱讀量.

jianshu-each-icon.png

現在我們已經能夠定位到全部的閱讀量小圖示,現在思考如何定位到旁邊的真正閱讀量呢?

<div class="meta">
    <span class="jsd-meta">
      <i class="iconfont ic-paid1"></i> 0.2
    </span>
    <a target="_blank" href="/p/3441940065b5">
        <i class="iconfont ic-list-read"></i> 2
    </a>        
    <a target="_blank" href="/p/3441940065b5#comments">
      <i class="iconfont ic-list-comments"></i> 0
    </a>      
    <span><i class="iconfont ic-list-like"></i> 1</span>
    <span class="time" data-shared-at="2019-04-12T10:39:57+08:00">昨天 10:39</span>
</div>
複製程式碼

分析文章結構,我們發現閱讀量是小圖示的父節點的內容,這一下就簡單了,我們順藤摸瓜定位到父節點自然就能定位到閱讀量了!

$("#list-container .ic-list-read").each(function(idx,ele){
    console.log($(ele).parent().text().trim());
});
複製程式碼

jianshu-locate-read.png

現在既然已經能夠定位到閱讀量,那麼首先累加求和就很簡單了.

//閱讀量
var readCount = 0;
$("#list-container .ic-list-read").each(function(idx,ele){
    readCount += parseInt($(ele).parent().text().trim());
});
console.log("閱讀量: " + readCount);
複製程式碼

jianshu-read-count-preview.png

小結

首先分析文章基本結構發現,簡書的閱讀量需要定位到閱讀量小圖示,進而定位到父節點,然後父節點的內容才是真正的閱讀量.

定位到真正的閱讀量後,一切問題迎刃而解,總結一下新增 jQuery 知識點.

定位到當前節點的父節點: $(ele).parent()

完整示例:

//閱讀量
var readCount = 0;
$("#list-container .ic-list-read").each(function(idx,ele){
    readCount += parseInt($(ele).parent().text().trim());
});
console.log("閱讀量: " + readCount);

//評論量
var commendCount = 0;
$("#list-container .ic-list-comments").each(function(idx,ele){
    commendCount += parseInt($(ele).parent().text().trim());
});
console.log("評論量: " + commendCount);

//喜歡量
var recommendCount = 0;
$("#list-container .ic-list-like").each(function(idx,ele){
    recommendCount += parseInt($(ele).parent().text().trim());
});
console.log("喜歡量: " + recommendCount);
複製程式碼

部落格園

部落格園的文章列表比較復古,傳統的 table 佈局,是這幾個平臺中最簡單的,基本上不同怎麼介紹.

cnblogs-selector-analysis.png

複製到閱讀量選擇器: #post-row-10694598 > td:nth-child(4) 此時再結合文章結構,因此我們可以得到全部文章的閱讀量選擇器.

$("#post_list td:nth-child(4)")
複製程式碼

接下來需要遍歷陣列,看看能否抓取到當前頁面全部文章的閱讀量.

$("#post_list td:nth-child(4)").each(function(idx,ele){
    console.log($(ele).text().trim());
});
複製程式碼

cloud-tencent-each-read.png

成功抓取到閱讀量,現在開始累加當前頁面全部文章的閱讀量.

//閱讀數
var readCount = 0;
$("#post_list td:nth-child(4)").each(function(idx,ele){
    readCount += parseInt($(ele).text().trim());
});
console.log("閱讀數: " + readCount);
複製程式碼

cnblogs-read-count-preview.png

小結

中規中矩的傳統 table 佈局,只需要順序定位到具體的元素即可,需要注意的是,部落格園文章頁面採用了分頁,如果需要統計全部文章的閱讀量,需要將每頁的閱讀量手動累加計算.

完整示例:

//評論數
var commendCount = 0;
$("#post_list td:nth-child(3)").each(function(idx,ele){
    commendCount += parseInt($(ele).text().trim());
});
console.log("評論數: " + commendCount);

//閱讀數
var readCount = 0;
$("#post_list td:nth-child(4)").each(function(idx,ele){
    readCount += parseInt($(ele).text().trim());
});
console.log("閱讀數: " + readCount);
複製程式碼

騰訊雲社群

大致分析騰訊雲社群的文章結構,基本上和簡書結構差不多,既可以像簡書那種採用圖示定位方式,也可以像慕課網和部落格園那種直接順序定位.

為了較為精準的定位,現在採用圖示定位方式來獲取閱讀量.

cloud-tencent-selector-analysis.png

#react-root > div:nth-child(1) > div.J-body.com-body.with-bg > section > div > section > div > div.com-log-list > section:nth-child(1) > section > div > div > span > span
複製程式碼

既然要根據圖示定位,我們需要分析圖示和閱讀量的關係.

<div class="com-operations com-article-panel-operations">
    <span class="com-opt-link">
        <i class="com-i-view"></i>
        <span class="text">76</span>
    </span>
    <a href="javascript:;" class="com-opt-link">
        <i class="com-i-like"></i>
        <span class="text">3</span>
    </a>
</div>
複製程式碼

因此,我們需要做如下改造才能定位到與閱讀量.

$("#react-root .com-i-view").each(function(idx,ele){
    console.log($(ele).next().text().trim());
});
複製程式碼

cloud-tencent-each-read.png

定位到閱讀量,接下來就是簡單的資料累加求和了.

//閱讀量
var readCount = 0;
$("#react-root .com-i-view").each(function(idx,ele){
    readCount += parseInt($(ele).next().text().trim());
});
console.log("閱讀量: " + readCount);
複製程式碼

cloud-tencent-read-count-preview.png

小結

騰訊雲社群和簡書一樣,採用的分頁疊加模式,因此需要統計全部文章的話,只需要一直滾動直到載入出全部文章即可.

總結一下涉及到的新增 jQuery 知識點:

獲取當前節點的下一個節點: $(ele).next()

完整示例:

//閱讀量
var readCount = 0;
$("#react-root .com-i-view").each(function(idx,ele){
    readCount += parseInt($(ele).next().text().trim());
});
console.log("閱讀量: " + readCount);

//點贊量
var recommendCount = 0;
$("#react-root .com-i-like").each(function(idx,ele){
    recommendCount += parseInt($(ele).next().text().trim());
});
console.log("點贊量: " + recommendCount);
複製程式碼

小結

本文通過 jQuery 方式直接抓取文章資料,簡單方便,學習成本低,能夠快速上手.

慕課網和部落格園的文章列表存在分頁,如果需要統計全部文章瀏覽量,需要將每一頁的文章累加,直到最後一頁. 簡書和騰訊雲社群的文章列表雖然也有分支,但會自動累加,所以統計全部文章時只需要先等全部文章載入完畢,再利用 js 指令碼一次性統計即可.

好了,本次分享到此結束,如果你覺得本文對你有所幫助,歡迎分享讓更多人看到哦,對了,上一篇文章也是解決統計問題的,不過使用的是 java 讀取 csv 檔案方式,如果有興趣,也可以看一看.

相關文章