關於寫做那些事之終於仍是沒法忍受純人工統計數據

背景

做爲正在探索如何寫做並發表到各大博客平臺的新人,目前雖然已基本弄清寫做和發表的基本流程,可是離打造我的知名度還差很大很大一段距離.java

尤爲處於新手階段,須要的更是自信與外界的積極反饋,看着各平臺日益增加的閱讀量和粉絲量,心中天然不甚欣喜.git

可是,持續的技術輸出可否堅持下去很大程度上靠的是外界的積極反饋,若是寫的文章基本沒人看,或者反映並不理想,估計也很難再堅持創做了.程序員

因此筆者天天晚上都會統計一下各個平臺的數據,看一下有哪些收穫,只有看得見的數據才能給我安全感和自信心.github

下面簡單展現一下每日數據統計效果:apache

每日數據統計

這裏列出的平臺默認是沒有提供數據分析功能,而有些平臺已經提供數據分析,說不定還要豐富圖表分析功能,天然不用像下面這般複雜操做.json

因此,針對沒有提供數據分析的平臺,只好採用人工方式進行每日數據統計,一開始文章比較少,用肉眼加計算器就能很輕鬆獲得閱讀量和粉絲數等數據.數組

可是,隨着文章的每日更新,不斷累加的文章愈來愈多,人工方式簡直讓我崩潰,好比昨晚在統計慕課網手記相關數據時就意外被一旁的小侄子打斷三次!安全

簡直不可忍受,窮則思變,懶則想法偷懶,因此是時候探索新的方式解決純手動的弊端了!併發

全網彙總數據

other-static-overview-201904.png

慕課手記

other-static-imooc-201904.png

簡書

other-static-jianshu-201904.png

博客園

other-static-cnblogs-201904.png

騰訊雲社區

other-static-tencent-cloud-201904.png

圖表渲染效果來自 gitbookchart 插件,詳情請參考 官網文檔maven

懶則想法偷懶

回顧操做流程

要想解放重複勞動量,必須先知道問題瓶頸,如今先回顧一下手動操做流程.

  1. 登陸各大博客平臺後臺,找到文章列表.
  2. 打開計算器按照閱讀量等指標累加每篇文章的相關數據.
  3. 更新統計頁面數據,利用 chart 插件渲染圖標.
  4. 修改 chart 渲染數據語法,截圖渲染效果.
  5. 確認渲染效果並推送到 github 網站

原本沒必要利用截圖表示圖表的,只是無奈 github 不支持 chart 插件語法,只好用截圖代替了.

思考問題瓶頸

分析上述流程後不難發現,最複雜也是最費時費力的即是第二步的數據統計,因爲要肉眼統計文章並用計算器累加,簡直是手腦並用,只有高度專一才能保證統計數據的準確性和可靠性.

這也就解釋了被打斷三次後的崩潰了,找到問題的根源了,想辦法如何解決吧!

最容易想到的解決辦法是手動複製文章列表數據,而後程序分析提取關鍵數據,最後再統計數據.

又是三步操做,再分解一下步驟,看看目前可以解決哪部分.

  1. 手動複製文章列表數據
  2. 程序分析提取關鍵數據
  3. 統計指標數據

在這三步中,只有第二步最爲關鍵,也是目前我能作到的事情,由於第一步可能須要爬蟲技術或模擬接口調用,整體來講,整體來講仍是比較麻煩的,之後再繼續優化吧.

梳理操做流程

所以,如今先着手如何將複製後的文章列表轉化成程序可以處理的文件格式,進而調用程序統計.

下面以慕課網手記文章爲例,簡單介紹下處理流程.

手動複製文章

imooc-copy.gif

如今文章已複製到文件,應該保存成什麼格式呢?這又是一個思考點.

imooc-without-suffix.png

因爲文件內容最終須要被程序處理,而程序處理要求數據須要具有必定的格式,所以天然不能是 txtword 這類文檔,日常接觸比較多的文檔數據處理通常就是 excel 或者 json 類型的文檔.

這裏須要 excel 這種格式文檔,可是 excel 比較笨重,還須要相關軟件才能打開 excel 文件,好像並非很適合,怎麼辦呢?

可是我真的須要這種一行一行的數據格式啊,有沒有折中的處理方案?

固然有!輕量級的 csv 格式不是巧合適合簡單文檔處理嗎?

csvexcel 具備相似的特徵,大致上都是一行一行一列一列地存儲數據,最適合統計數據了.

看着亂七八糟的文章列表,csv 也沒法處理這種複雜數據啊,接下來仍是要手動格式化數據,整理一下數據.

imooc-with-csv.png

程序分析提取

至此,咱們已經完成數據分析的第一步了,接下來是如何讀取 csv 文件,因爲本人是 java 程序員,因此我要看一下 java 如何處理 csv 文件.

需求很簡單,編寫一個 csv 工具類並實現基本的寫入和讀取操做便可.

說到工具類固然首選現成的開源工具了,畢竟小小的需求不值得造輪子.

尋求解決方案

說到開源工具,腦海中第一個閃現的是 Apache Commons 工具類,因此先去 maven 上搜一下有沒有 csv 相關的工具類.

在線搜索 commons-csv

maven-search-csv.png

天不負我!果真有 csv 相關工具類,下面就開始研究如何調用吧!

  • 集成 commons-csv 工具類
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-csv -->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-csv</artifactId>
    <version>1.6</version>
</dependency>
  • 編寫工具類
/**
 * 寫入csv文件
 *
 * @param data     數據內容
 * @param filePath 文件路徑
 * @throws IOException
 **/
public static void writeCsv(List<String[]> data, String filePath) throws IOException {
    FileWriter fw = new FileWriter(new File(filePath));
    final CSVPrinter printer = CSVFormat.EXCEL.print(fw);
    printer.printRecords(data);
    printer.flush();
    printer.close();
}

/**
 * 讀取csv文件
 *
 * @param filePath 文件路徑
 * @return CSVRecord 迭代對象
 * @throws IOException
 **/
public static Iterable<CSVRecord> readCSV(String filePath) throws IOException {
    InputStream inputStream = new FileInputStream(filePath);
    InputStreamReader isr = new InputStreamReader(inputStream);
    Iterable<CSVRecord> records = CSVFormat.EXCEL.parse(isr);
    return records;
}

/**
 * 測試寫入並讀取csv 文件
 */
private static void testWriteAndRead() throws IOException {
    //寫入數據
    List<String[]> data = new ArrayList<String[]>();
    data.add(new String[]{"張三", "18", "3000"});
    data.add(new String[]{"李四", "20", "4000"});
    data.add(new String[]{"王二", "25", "5000"});

    //寫入文件路徑
    String path = "/Users/sunpo/Downloads/testWriteAndRead.csv";

    //寫入 csv 文件
    writeCsv(data, path);

    //讀取文件
    Iterable<CSVRecord> records = readCSV(path);
    for (CSVRecord record : records) {
        for (String string : record) {
            System.out.print(string);
            System.out.print(" ");
        }
        System.out.println();
    }
}
  • 測試寫入並讀取功能

test-write-read-csv.png

測試結果然實可用,工具類基本功能編寫完成.

test-write-read-csv-result.png

制定解決方案

已經有了 csv 工具類,那麼如今就要想辦法解決實際問題,再看一下當前慕課網手記的內容格式吧!

148瀏覽 2推薦 0評論
204瀏覽 2推薦 0評論
181瀏覽 2推薦 0評論

分析上述內容格式有如下特色:

  • 內容數據一行一條數據,可能須要換行符問題
  • 每一行數據以空格分割,可分割成數組或列表再處理
  • 已分割後的列表項包括了有效數據和文字說明,可能須要過濾出有效數據

按照上述分析結果,開始 coding 逐個解決,下面展現下關鍵代碼.

  • 按照空格將每一行數據分割成列表
List<String> row = StringTools.splitToListString(string, " ");

StringTools.splitToListString 方式是筆者封裝的分割字符串方法,目的將字符串按照指定分隔符分割成字符串列表

  • 處理分割後字符串列表並過來出有效數據
String readCountWithDescString = row.get(0);
String readCountString = StringUtils.substringBefore(readCountWithDescString, "瀏覽");

String recommendCountWithDescString = row.get(1);
String recommendCountString = StringUtils.substringBefore(recommendCountWithDescString, "推薦");

String commentCountWithDescString = row.get(2);
String commentCountString = StringUtils.substringBefore(commentCountWithDescString, "評論");

StringUtils.substringBefore 方法也是Apache Commons 工具類,具體來源於 org.apache.commons.lang3 ,下述涉及到的 StringUtils 靜態方法 也是,再也不單獨說明.

  • 最後一步即統計分析
//瀏覽數
int readCount = 0;
//推薦數
int recommendCount = 0;
//評論數
int commentCount = 0;

readCount += Integer.parseInt(readCountString);
recommendCount += Integer.parseInt(recommendCountString);
commentCount += Integer.parseInt(commentCountString);
實施解決方案

如此一來,三步均已解決,如今運行如下統計方法,看一下真實效果如何.

/**
 * 統計慕課手記
 *
 * @throws IOException
 */
private static void countImooc() throws IOException {
    //昨日統計數據
    String yesterday = DateFormatUtils.format(DateUtils.addDays(new Date(), -1), "yyyyMMdd");
    String path = String.format("/Users/sunpo/Documents/workspace/count/imooc-%s.csv", yesterday);

    //總行數
    int allRows = 0;
    //有效行數
    int allValidRows = 0;
    //當前行是否有效
    boolean isValidRow = true;
    //瀏覽數
    int readCount = 0;
    //推薦數
    int recommendCount = 0;
    //評論數
    int commentCount = 0;

    Iterable<CSVRecord> records = readCSV(path);
    for (CSVRecord record : records) {
        allRows++;

        for (String string : record) {
            System.out.println(string);

            if (StringUtils.isBlank(string)) {
                isValidRow = false;
                break;
            }

            List<String> row = StringTools.splitToListString(string, " ");

            String readCountWithDescString = row.get(0);
            String readCountString = StringUtils.substringBefore(readCountWithDescString, "瀏覽");

            String recommendCountWithDescString = row.get(1);
            String recommendCountString = StringUtils.substringBefore(recommendCountWithDescString, "推薦");

            String commentCountWithDescString = row.get(2);
            String commentCountString = StringUtils.substringBefore(commentCountWithDescString, "評論");

            readCount += Integer.parseInt(readCountString);
            recommendCount += Integer.parseInt(recommendCountString);
            commentCount += Integer.parseInt(commentCountString);
        }

        if (isValidRow) {
            allValidRows++;
        }
        isValidRow = true;
    }
    System.out.println();
    System.out.println(String.format("[慕課手記] 一共讀取%d行,有效行: allValidRows = %d ,其中瀏覽數: readCount = %d ,推薦數: recommendCount = %d ,評論數: commentCount = %d", allRows, allValidRows, readCount, recommendCount, commentCount));
    System.out.println();
}

imooc-statics-result.png

很完美,終於沒必要再肉眼統計數據了,雖然很長程度上仍然依賴人工整理好 csv 文件,可是目前已經解決了純手動的弊端.

所以,上述解決方案是半手動的方式,仍然還有不少能夠優化的地方,等下次忍受不了這種方案時再解決!

小結

本文主要介紹了純手工統計報表遇到的諸多問題,尋求一種相對簡單的解決方案.

基本流程大體能夠分爲下述流程:

  1. 手動複製文章列表(包括閱讀量,評論量和點贊數),並整理成標準的 csv 格式文件.
  2. 編寫各個平臺的 csv 工具處理類,解析並統計 csv 文件內容.
  3. 運行工具類獲得最終統計數據,大功告成!

本文主要介紹的是解決問題的思路,對於其中涉及到的相關技術點並未深刻展開,關鍵源碼已經貼上,若是還想要更詳細的完整源碼,能夠留言回覆.

相關文章
相關標籤/搜索