Develop/Kotlin

[kotlin] 코틀린 Android 공공데이터 오픈 API 활용(XML 문서)

JunJangE 2021. 8. 4. 18:07

이번에는 다양한 데이터가 있는 공공데이터 포털을 통해 오픈 API를 활용해려고한다. 

 

공공데이터 포털

국가에서 보유하고 있는 다양한 데이터를『공공데이터의 제공 및 이용 활성화에 관한 법률(제11956호)』에 따라 개방하여 국민들이 보다 쉽고 용이하게 공유•활용할 수 있도록 공공데이터(Datase

www.data.go.kr

공공데이터 활용신청

우선 공공데이터 포털에 들어가 회원가입, 로그인 후 자신이 원하는 공공데이터 오픈 API를 선택한다.

예제에서는 한국관광공사_고캠핑정보 조회 서비스로 활용신청 했고 활용신청 후 1~ 2시간 후에 승인이 난다.

공공데이터 활용신청

위 오픈API 응답 표준은 XML 이며, JSON을 요청할 경우“&_type=json”을 추가하여 요청 가능하다.

하지만 여기 예제에서는 XML 형식으로 구현했기때문에 JSON 형식으로는 요청하지 못한다.

JSON 형식은 다음 링크를 통해 수행하자.

 

[kotlin] 코틀린 Android 공공데이터 오픈 API 활용(JSON 문서)

이전에 XML 형식으로 오픈 API를 요청하여 데이터를 확인해 보았다. [kotlin] 코틀린 Android 공공데이터 오픈 API 활용(XML) 이번에는 다양한 데이터가 있는 공공데이터 포털을 통해 오픈 API를 활용해려

fre2-dom.tistory.com

그럼 오픈 API에서 어떠한 정보를 활용할지 선택하자.

예제에서는 한국관광공사_고캠핑정보 조회 서비스 기본 정보 목록 조회를 활용하려고한다.

오픈 API 상세기능

오픈 API를 신청한 창에서 밑으로 내려보면 상세기능이 있다.

상세기능에서 기본 정보 목록 조회를 조회하여 요청변수를 확인한다.

요청변수에서 항목구분을 보면 필수인지 옵션인지 나타나있는데, 이것을 가지고 우리가 원하는 데이터를 가져올 수 있다. 필수 항목은 무조건 적어주고 옵션인 부분은 필요에 따라 적는다.

오픈 API 활용

1~ 2시간 후에 마이 페이지에 들어가 승인이 되었는지 확인한다.

공공데이터 활용 승인

승인이 되면 승인된 오픈API 창을 클릭하여 밑으로 내려 활용신청 상세기능정보를 확인한다.

활용신청 상세기능정보를 확인하면 우리가 가져올 기본 정보 목록 조회가 2번째에 있는 것을 확인할 수 있다.

활용신청 상세기능정보

기본 정보 목록 조회 미리보기에서 확인을 눌러보면 다음 창이 나온다.

 

인증키

위에 빨간 테두디로 있는 인증키를 요청변수에 복붙하고 미리보기를 눌러 어떠한 데이터가 나오는지 확인한다.

미리보기

우리는 위에서 나오는 데이터를 가져와 보는 것을 해보자.

addr1 = 주소

facltNm = 캠핑장 이름

mapX = 위도

mapY = 경도

induty = 업종

우리는 위 정보만을 가져오는 코드를 작성하자.

주석을 잘 확인하면서 코드를 적으면 좋을 것 같다.

MainActivity

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.Button
import kotlinx.android.synthetic.main.activity_main.*
import org.w3c.dom.Document
import org.w3c.dom.Node
import org.w3c.dom.NodeList
import org.w3c.dom.Element
import javax.xml.parsers.DocumentBuilderFactory


var text = ""

class MainActivity : AppCompatActivity() {


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val button = findViewById<Button>(R.id.button)

        textView.text = ""
        
        // 키 값
        val key = "키값"
        // 현재 페이지번호
        val pageNo = "&pageNo=1"
        // 한 페이지 결과 수
        val numOfRows ="&numOfRows=5"
        // AND(안드로이드)
        val MobileOS = "&MobileOS=AND"
        // 서비스명 = 어플명
        val MobileApp = "&MobileApp=AppTest"
        // API 정보를 가지고 있는 주소
        val url = "http://api.visitkorea.or.kr/openapi/service/rest/GoCamping/basedList?serviceKey="+key+pageNo+numOfRows+MobileOS+MobileApp

        // 버튼을 누르면 쓰레드 동작
        button.setOnClickListener {
            // 쓰레드 생성
            val thread = Thread(NetworkThread(url))
            thread.start() // 쓰레드 시작
            thread.join() // 멀티 작업 안되게 하려면 start 후 join 입력

            // 쓰레드에서 가져온 api 정보 텍스트에 뿌려주기
            textView.text = text
        }
    }

}

class NetworkThread(
    var url: String): Runnable {

    override fun run() {

        try {

            val xml : Document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(url)


            xml.documentElement.normalize()

            //찾고자 하는 데이터가 어느 노드 아래에 있는지 확인
            val list:NodeList = xml.getElementsByTagName("item")

            //list.length-1 만큼 얻고자 하는 태그의 정보를 가져온다
            for(i in 0..list.length-1){

                val n:Node = list.item(i)

                if(n.getNodeType() == Node.ELEMENT_NODE){

                    val elem = n as Element

                    val map = mutableMapOf<String,String>()


                    // 이부분은 어디에 쓰이는지 잘 모르겠다.
                    for(j in 0..elem.attributes.length - 1) {

                        map.putIfAbsent(elem.attributes.item(j).nodeName, elem.attributes.item(j).nodeValue)

                    }


                    println("=========${i+1}=========")
                    text += "${i + 1}번 캠핑장 \n"

                    println("1. 주소 : ${elem.getElementsByTagName("addr1").item(0).textContent}")
                    text += "1. 주소 : ${elem.getElementsByTagName("addr1").item(0).textContent} \n"

                    println("2. 캠핑장 이름 : ${elem.getElementsByTagName("facltNm").item(0).textContent}")
                    text += "2. 캠핑장 이름 : ${elem.getElementsByTagName("facltNm").item(0).textContent} \n"

                    println("3. 위도 : ${elem.getElementsByTagName("mapX").item(0).textContent}")
                    text += "3. 위도 : ${elem.getElementsByTagName("mapX").item(0).textContent} \n"

                    println("4. 경도 : ${elem.getElementsByTagName("mapY").item(0).textContent}")
                    text += "4. 경도 : ${elem.getElementsByTagName("mapY").item(0).textContent} \n"

                    println("5. 업종 : ${elem.getElementsByTagName("induty").item(0).textContent}")
                    text += "5. 업종 : ${elem.getElementsByTagName("induty").item(0).textContent} \n"

                }
            }
        } catch (e: Exception) {
            Log.d("TTT", "오픈API"+e.toString())
        }
    }
}

activitiy.main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"
    android:orientation="vertical">


    <Button
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Button" />

    <TextView
        android:id="@+id/textView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="TextView" />
</LinearLayout>

AndroidMainfest.xml

 <!--인터넷 권한 허용 -->
    <uses-permission android:name="android.permission.INTERNET"/>
    
    
    <!-- <application
       android:usesCleartextTraffic="true" 인터넷 웹뷰로 불러올때 s를 만들어준다?
       앱이 일반 텍스트 HTTP와 같은 일반 텍스트 네트워크 트래픽을 사용하는지 여부를 나타낸다.
       -->

위 코드를 모두 작성하고 실행하면 다음과 같은 결과를 얻을 수 있다.

logcat 결과
<결과 화면>

이렇게 공공데이터 포털을 통해 오픈 API를 가져오고 XML 파싱으로 데이터를 불러왔다. 

이제부터는 가져온 데이터를 토대로 응용하는 방법에 대해 공부해봐야할 것 같다.

참고

 

[코틀린] 공공api 가져오기

회사에서 인턴하게 되었는데 첫일이 공공api 에서 데이터 가져오는 일을 하게 될줄 몰랐다. 그것도 코틀린으로 ㄷㄷ 크롤링도 안해봤고 코틀린도 안해봐서 코드 짜는데 좀 걸렸다. 공공데이터포

gomip.tistory.com

github

 

GitHub - junjange/Kotlin-Learning: 코틀린 학습

코틀린 학습. Contribute to junjange/Kotlin-Learning development by creating an account on GitHub.

github.com