• 서울시 지하철 공공데이터 API 파싱하기

    2022. 12. 8.

    by. namudongs

    OPEN API

    웹사이트나 어플리케이션을 만들다 보면 다른 곳에서 데이터를 가져와야 할 때가 있다. 필요한 데이터들은 기업이나 공공기관에서 공개하여 배포하기도 하는데, 대표적인 예가 OP.GG나 FOW.KR같은 게임 전적검색 웹사이트이다. 이러한 웹사이트들은 게임사에서 제공하는 외부 API를 받아와 가공하여 사용자에게 서비스를 제공하는 웹사이트인데 국가나 공공기관에서도 사회기반시설의 API를 공개하여 사용할 수 있도록 하고 있다. 우리가 아는 카카오지하철이나 카카오버스가 대표적인데, 지자체나 공공기관에서 정보를 제공받아 가공하여 사용자들에게 서비스를 제공하고 있다. 카카오지하철, 카카오버스 앱에서 <설정 - 정보 제공처>를 보면 제공처를 확인할 수 있다.

     

    공공기관 API 데이터 신청/발급

    공공기관 API 데이터의 사용은 공공데이터포털에서 할 수 있다. 

    서울시의 지하철 실시간 도착정보 오픈API를 이용해보자.

    API 페이지를 보면 샘플 URL을 확인할 수 있으니 참고할 수 있다.

    샘플 URL에서 (인증키) 부분을 sample로 바꾸면 내용을 확인할 수 있다.

    또 URL에서 xml 부분을 json으로 바꾸면 xml 파일이 아닌 json 파일로 받을 수 있다.

     

    MainActivity.java

    public class MainActivity extends AppCompatActivity {
    
        TextView textView;
        XmlPullParser xpp;
        String data;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            textView = findViewById(R.id.textView);
        }
    
        public void mOnClick(View v) {
            switch (v.getId()) {
                case R.id.button:
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            data = getXmlData();
    
                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    textView.setText(data);
                                }
                            });
                        }
                    }).start();
                    break;
            }
        }
    
        String getXmlData() {
            StringBuffer buffer = new StringBuffer();
            String queryUrl = "http://swopenapi.seoul.go.kr/api/subway/sample/xml/realtimeStationArrival/0/5/서울";
    
            try {
                URL url = new URL(queryUrl);
                InputStream is = url.openStream();
    
                XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
                XmlPullParser xpp = factory.newPullParser();
                xpp.setInput(new InputStreamReader(is, "UTF-8"));
    
                String tag;
    
                xpp.next();
                int eventType = xpp.getEventType();
                while (eventType != XmlPullParser.END_DOCUMENT) {
                    switch(eventType) {
                        case XmlPullParser.START_DOCUMENT:
                            buffer.append("파싱 시작...\n\n");
                            break;
    
                        case XmlPullParser.START_TAG:
                            tag = xpp.getName();
    
                            if (tag.equals("row"));
                            else if (tag.equals("subwayId")){
                                buffer.append("지하철호선ID : ");
                                xpp.next();
                                buffer.append(xpp.getText());
                                buffer.append("\n");
                            }
                            else if (tag.equals("updnLine")){
                                buffer.append("상하행선구분 : ");
                                xpp.next();
                                buffer.append(xpp.getText());
                                buffer.append("\n");
                            }
                            else if (tag.equals("trainLineNm")){
                                buffer.append("도착지방면 : ");
                                xpp.next();
                                buffer.append(xpp.getText());
                                buffer.append("\n");
                            }
                            else if (tag.equals("subwayHeading")){
                                buffer.append("내리는문방향 : ");
                                xpp.next();
                                buffer.append(xpp.getText());
                                buffer.append("\n");
                            }
                            else if (tag.equals("statnFid")){
                                buffer.append("이전지하철역ID : ");
                                xpp.next();
                                buffer.append(xpp.getText());
                                buffer.append("\n");
                            }
                            else if (tag.equals("statnTid")){
                                buffer.append("다음지하철역ID : ");
                                xpp.next();
                                buffer.append(xpp.getText());
                                buffer.append("\n");
                            }
                            else if (tag.equals("statnId")){
                                buffer.append("지하철역ID : ");
                                xpp.next();
                                buffer.append(xpp.getText());
                                buffer.append("\n");
                            }
                            else if (tag.equals("stattNm")){
                                buffer.append("지하철역명 : ");
                                xpp.next();
                                buffer.append(xpp.getText());
                                buffer.append("\n");
                            }
                            else if (tag.equals("tmsitCo")){
                                buffer.append("환승노선수 : ");
                                xpp.next();
                                buffer.append(xpp.getText());
                                buffer.append("\n");
                            }
                            else if (tag.equals("ordkey")){
                                buffer.append("도착예정열차순번 : ");
                                xpp.next();
                                buffer.append(xpp.getText());
                                buffer.append("\n");
                            }
                            else if (tag.equals("subwayList")){
                                buffer.append("연계호선ID : ");
                                xpp.next();
                                buffer.append(xpp.getText());
                                buffer.append("\n");
                            }
                            else if (tag.equals("statnList")){
                                buffer.append("연계지하철역ID : ");
                                xpp.next();
                                buffer.append(xpp.getText());
                                buffer.append("\n");
                            }
                            else if (tag.equals("btrainSttus")){
                                buffer.append("열차종류 : ");
                                xpp.next();
                                buffer.append(xpp.getText());
                                buffer.append("\n");
                            }
                            else if (tag.equals("barvlDt")){
                                buffer.append("열차도착예정시간 : ");
                                xpp.next();
                                buffer.append(xpp.getText());
                                buffer.append("\n");
                            }
                            else if (tag.equals("btrainNo")){
                                buffer.append("열차번호 : ");
                                xpp.next();
                                buffer.append(xpp.getText());
                                buffer.append("\n");
                            }
                            else if (tag.equals("bstatnId")){
                                buffer.append("종착지하철역ID : ");
                                xpp.next();
                                buffer.append(xpp.getText());
                                buffer.append("\n");
                            }
                            else if (tag.equals("bstatnNm")){
                                buffer.append("종착지하철역명 : ");
                                xpp.next();
                                buffer.append(xpp.getText());
                                buffer.append("\n");
                            }
                            else if (tag.equals("recptnDt")){
                                buffer.append("열차도착정보를 생성한 시각 : ");
                                xpp.next();
                                buffer.append(xpp.getText());
                                buffer.append("\n");
                            }
                            else if (tag.equals("arvlMsg2")){
                                buffer.append("첫번째도착메세지 : ");
                                xpp.next();
                                buffer.append(xpp.getText());
                                buffer.append("\n");
                            }
                            else if (tag.equals("arvlMsg3")){
                                buffer.append("두번째도착메세지 : ");
                                xpp.next();
                                buffer.append(xpp.getText());
                                buffer.append("\n");
                            }
                            else if (tag.equals("arvlCd")){
                                buffer.append("도착코드 : ");
                                xpp.next();
                                buffer.append(xpp.getText());
                                buffer.append("\n");
                            }
                            break;
    
                        case XmlPullParser.TEXT:
                            break;
                        case XmlPullParser.END_TAG:
                            tag = xpp.getName();
    
                            if (tag.equals("row")) buffer.append("\n");
                            break;
                    }
                    eventType = xpp.next();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            buffer.append("파싱 끝\n");
            return buffer.toString();
        }
    }

    실행 화면

    XML을 파싱하여 위처럼 필요한 데이터만 뽑아올 수 있다.

    댓글