250x250
Notice
Recent Posts
Recent Comments
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 28 | 29 | 30 |
Tags
- 막내의막무가내 플러터
- 막무가내
- 막내의막무가내 안드로이드 코틀린
- 막내의막무가내 안드로이드 에러 해결
- 주택가 잠실새내
- 프로그래머스 알고리즘
- 안드로이드 sunflower
- 막내의 막무가내 알고리즘
- 부스트코스
- 막내의막무가내 SQL
- 막내의막무가내 알고리즘
- 막내의막무가내 플러터 flutter
- 막내의막무가내 일상
- 막내의막무가내 코틀린 안드로이드
- 안드로이드
- Fragment
- 안드로이드 Sunflower 스터디
- 막내의막무가내 프로그래밍
- flutter network call
- 막내의막무가내 안드로이드
- 주엽역 생활맥주
- 막내의막무가내 코틀린
- 부스트코스에이스
- 막내의막무가내 목표 및 회고
- 막내의막무가내
- 프래그먼트
- 2022년 6월 일상
- 막내의막무가내 코볼 COBOL
- 막내의막무가내 rxjava
- 막내의 막무가내
Archives
- Today
- Total
막내의 막무가내 프로그래밍 & 일상
[코틀린] Jsoup 파싱 라이브러리 사용 기록 본문
728x90
[2021-04-13 업데이트]
학교 공지사항 불러오는 앱을 아키텍처 공부용으로 간단하게 시간날때 해보고 있습니다.
https://github.com/florent37/RxRetroJsoup
처음에 RxJsoup 이라고 위 라이브러리를 사용해봤었습니다. RxJava 와 Jsoup 을 연결해준 라이브러리라고 보면 됩니다.
그런데 하라는대로 다했는데 안되고 여기의 샘플 프로젝트의 주소로도 했는데 안되길래 기본 Jsoup을 사용하기로 했습니다.
Jsoup 은 처음 사용해봤는데 나중에도 간단한 파싱을 하기 위해 기록용 포스팅을 남깁니다.
주석으로 설명을 달았습니다.
[학교 공지 html 입니다]
[코틀린 Jsoup 구현입니다. ]
위와 같이 tr class 가 "" 로 class 이름이 없어 번호, 공지제목, 링크 를 한번에 갖고 올 수 가 없어 어쩔 수 없이 각각 두개로 나눠서 가져왔습니다. 이 때 withIndex() 코틀린 반복문 함수를 사용했는데 알고리즘을 할 때 안뒤로 유용하게 잘 사용하고 있습니다. ㅎㅎ
package com.mtjin.cnunoticeapp.data.bachelor.source.remote
import android.util.Log
import com.mtjin.cnunoticeapp.data.bachelor.BachelorNotice
import io.reactivex.Single
import org.jsoup.Jsoup
import org.jsoup.nodes.Document
import org.jsoup.select.Elements
class BachelorNoticeRemoteDataSourceImpl : BachelorNoticeRemoteDataSource {
override fun requestNotice(): Single<List<BachelorNotice>> {
val bachNoticeList: ArrayList<BachelorNotice> = ArrayList()
val doc: Document =
Jsoup.connect("https://computer.cnu.ac.kr/computer/notice/bachelor.do").get() // Base Url
val contentElements: Elements = doc.select("div[class=b-title-box]").select("a") // title, link
val idElements: Elements = doc.select("td[class=b-num-box]") // id값
for ((i, elem) in contentElements.withIndex()) {
Log.d("APPTEST", "" + idElements[i].text()) // 아이디
Log.d("APPTEST", elem.text()) // 제목
Log.d("APPTEST", "" + elem.attr("href")) // 링크
bachNoticeList.add(BachelorNotice(idElements[i].text(), elem.text(), elem.attr("href")))
}
return Single.just(bachNoticeList)
}
override fun requestNotice(offset: Int): Single<List<BachelorNotice>> {
TODO("Not yet implemented")
}
}
참고로 위와 같이 메인스레드에서 Jsoup 통신을하면 에러가난다
그러므로 밑과 같이 rxjava2 를 사용하거나 코루틴 , Asynctask 를 통해서 구현하도록하자
package com.mtjin.cnunoticeapp.data.bachelor.source.remote
import com.mtjin.cnunoticeapp.data.bachelor.BachelorNotice
import io.reactivex.Observable
import io.reactivex.Single
import org.jsoup.Jsoup
import org.jsoup.nodes.Document
import org.jsoup.select.Elements
class BachelorNoticeRemoteDataSourceImpl : BachelorNoticeRemoteDataSource {
override fun requestNotice(): Single<List<BachelorNotice>> {
return Single.fromObservable(
Observable.create {
val bachNoticeList: ArrayList<BachelorNotice> = ArrayList()
val doc: Document =
Jsoup.connect("https://computer.cnu.ac.kr/computer/notice/bachelor.do")
.get() // Base Url
val contentElements: Elements =
doc.select("div[class=b-title-box]").select("a") // title, link
val idElements: Elements = doc.select("td[class=b-num-box]") // id값
for ((i, elem) in contentElements.withIndex()) {
bachNoticeList.add(
BachelorNotice(
idElements[i].text(),
elem.text(),
elem.attr("href")
)
)
}
it.onNext(bachNoticeList)
it.onComplete()
}
)
}
override fun requestMoreNotice(offset: Int): Single<List<BachelorNotice>> {
return Single.fromObservable(
Observable.create {
val bachNoticeList: ArrayList<BachelorNotice> = ArrayList()
val doc: Document =
Jsoup.connect("https://computer.cnu.ac.kr/computer/notice/bachelor.do?mode=list&&articleLimit=10&article.offset=$offset")
.get() // Base Url
val contentElements: Elements =
doc.select("div[class=b-title-box]").select("a") // title, link
val idElements: Elements = doc.select("td[class=b-num-box]") // id값
for ((i, elem) in contentElements.withIndex()) {
if (idElements[i].text() != "공지") { // 공지는 매 페이지마다 있으므로 중복제거
bachNoticeList.add(
BachelorNotice(
idElements[i].text(),
elem.text(),
elem.attr("href")
)
)
}
}
it.onNext(bachNoticeList)
it.onComplete()
}
)
}
}
[로그 결과]
제대로 파싱이 되는걸 볼 수 있다.
댓글과 공감은 큰 힘이 됩니다. 감사합니다. !!!!
728x90
'안드로이드 > 코틀린 & 아키텍처 & Recent' 카테고리의 다른 글
Comments