Day17 - 解析推文

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

首先送出"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")
    }
}

解析结果


<<:  【从实作学习ASP.NET Core】Day20 | 前台 | 建立前台页面

>>:  Day 19 : 静态爬虫(下)

部署model on seldon(MinIO)

上一篇我们已使用notebook已经将训练好的model上传到MinIO储存空间, 本篇我们将使用s...

[Java Day03] 1.1. 变数

教材网址 https://coding104.blogspot.com/2021/06/java-v...

网拍的创业回亿:管理与经营(一)

我很重视客户的意见与收货速度。 当时我是网路拍卖的创办人,与客户约定好了要五天内到货。为了达成目标,...

Day05:【TypeScript 学起来】TS 指定型别的三种方法

Q: 为什麽一个男业务(30岁)会约我一个工程师(24岁)去园区的星巴克? A: 根据哥多年的经验...

[Day20] 参数(下)

其余参数(rest parameter) 上一篇提到,箭头函式无法使用 arguments 物件,所...