iT邦幫忙

2021 iThome 鐵人賽

DAY 17
0

今天先來初步的解析文章的推文。

首先送出"G"跳到文章的最後一頁,之後的功能也預計會從新的推文往舊的解析,但換頁這部分我還在思考,不會在今天的內容。

viewLifecycleOwner.lifecycleScope.launch(Dispatchers.IO) {
    PttClient.getInstance().send("G")
    delay(100L)
    Log.d(mTag, "current page:\n${PttClient.getInstance().getScreen()}")
    val rows = PttClient.getInstance().getScreen().split("\n")
    //TODO parsing.
}

Ptt看板設定

在開始解析前先來看一下Ptt的看板設定:
https://ithelp.ithome.com.tw/upload/images/20211002/201246028iYKFv2qSe.png
其中ia的開啟與否會影響推文時顯示的格式:
https://ithelp.ithome.com.tw/upload/images/20211002/20124602kylpFLqIwg.png
以上四行的設定分別是i關a關、i關a開、i開a關、i開a開。其中紅色覆蓋的是ID、綠色覆蓋的是IP。
因為我是在Ptt2做測試,因此最後面有多了一個"",目前Ptt是沒有這個字了。

對我們分析影響比較大的是IP的設定,需設計成IP顯示與否都能正確解析的Pattern。

Pattern

目前測試起來應該能符合的Pattern如下:
"(?<like>[推]|[→]|[噓])*[ ](?<id>.*)[:][ ](?<content>.*)[ ](?<ip>((.*\.){3}.*|[ ]))(?<date>../.. ..:..)"
若ip無開放的話會去抓空格,開放的話也能將ip抓出來。

Comment物件

data class Comment(
    val like: String,
    val id: String,
    val content: String,
    val ip: String,
    val time: String
) {
    override fun equals(other: Any?): Boolean {
        if (other is Comment) {
            return (other.hashCode() == hashCode()) ||
                    (like == other.like && id == other.id && content == other.content
                            && ip == other.ip && time == other.time)
        }
        return super.equals(other)
    }

    override fun hashCode(): Int {
        return super.hashCode()
    }
}

目前是先將上面抓出的項目都儲存起來,IP還在思考要不要存,因為應該是不會顯示。
另外有override equals方法,這是為了未來在更新推文時要比對用。

解析

承一開始的程式碼,當中的//TODO parsing.

val commentPattern =
    Pattern.compile("(?<like>[推]|[→]|[噓])*[ ](?<id>.*)[:][ ](?<content>.*)[ ](?<ip>((.*\.){3}.*|[ ]))(?<date>../.. ..:..)")
rows.forEach {
    val matcher = commentPattern.matcher(it)
    if (matcher.find()) {
        val like = matcher.group("like")!!.trim()
        val id = matcher.group("id")!!.trim()
        val content = matcher.group("content")!!.trim()
        val ip = matcher.group("ip")!!.trim()
        val date = matcher.group("date")!!.trim()

        val comment = Comment(
            like,
            id,
            content,
            ip,
            date
        )
        Log.d(mTag, "comment:$comment")
    }
}

解析結果


上一篇
Day16 - 進入和退出文章
下一篇
Day18 - 使用ViewBinding取代Kotlin Android Extension
系列文
花30天做個Android小專案30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言