본문 바로가기
프로그래밍/Python

[기상청 데이터 가져오기]

by Ohdumak 2018. 8. 13.

[기상청 데이터 가져오기]



기상청에서 제공하는 코드(좌표)정보 가져오기

    • 도/시 정보 구하기
      • 다음 URL을 통해서 json 형식의 도/시 정보를 구할 수 있다
      • "http://www.kma.go.kr/DFSROOT/POINT/DATA/top.json.txt"
        [{'value': '서울특별시', 'code': '11'}, {'value': '부산광역시', 'code': '26'}, {'value': '대구광역시', 'code': '27'}, {'value': '인천광역시', 'code': '28'}, {'value': '광주광역시', 'code': '29'}, {'value': '대전광역시', 'code': '30'}, {'value': '울산광역시', 'code': '31'}, {'value': '경기도', 'code': '41'}, {'value': '강원도', 'code': '42'}, {'value': '충청북도', 'code': '43'}, {'value': '충청남도', 'code': '44'}, {'value': '전라북도', 'code': '45'}, {'value': '전라남도', 'code': '46'}, {'value': '경상북도', 'code': '47'}, {'value': '경상남도', 'code': '48'}, {'value': '제주특별자치도', 'code': '50'}]

    • 시/군/구 정보 구하기
      • 도/시 code 정보를 바탕으로 URL을 통해서 json 형식의 시/군/구 정보를 구할 수 있다.
      • "http://www.kma.go.kr/DFSROOT/POINT/DATA/mdl." + topCode + ".json.txt"
      • 인천광역시의 시/군/구 구하기
        예) http://www.kma.go.kr/DFSROOT/POINT/DATA/mdl.28.json.txt

        [{'value': '중구', 'code': '28110'}, {'value': '동구', 'code': '28140'}, {'value': '남구', 'code': '28170'}, {'value': '연수구', 'code': '28185'}, {'value': '남동구', 'code': '28200'}, {'value': '부평구', 'code': '28237'}, {'value': '계양구', 'code': '28245'}, {'value': '서구', 'code': '28260'}, {'value': '강화군', 'code': '28710'}, {'value': '옹진군', 'code': '28720'}]
    • 읍/면/동 정보 구하기
      • 시/군/구 code 정보를 바탕으로 URL을 통해서 json 형식의 읍/면/동 정보를 구할 수 있다.
      • "http://www.kma.go.kr/DFSROOT/POINT/DATA/leaf." + mdlCode + ".json.txt"
      • 인천광역시 연수구의 읍/면/동 구하기
        예) http://www.kma.go.kr/DFSROOT/POINT/DATA/leaf.28185.json.txt

        [{'value': '옥련1동', 'y': '124', 'code': '2818563000', 'x': '54'}, {'value': '옥련2동', 'y': '124', 'code': '2818564000', 'x': '54'}, {'value': '선학동', 'y': '123', 'code': '2818575000', 'x': '55'}, {'value': '연수1동', 'y': '123', 'code': '2818576100', 'x': '55'}, {'value': '연수2동', 'y': '123', 'code': '2818576200', 'x': '55'}, {'value': '연수3동', 'y': '123', 'code': '2818576300', 'x': '55'}, {'value': '청학동', 'y': '124', 'code': '2818576600', 'x': '55'}, {'value': '동춘1동', 'y': '123', 'code': '2818578000', 'x': '55'}, {'value': '동춘2동', 'y': '123', 'code': '2818579000', 'x': '55'}, {'value': '동춘3동', 'y': '123', 'code': '2818579500', 'x': '55'}, {'value': '송도동', 'y': '123', 'code': '2818581000', 'x': '54'}]

XML 형식의 날씨 정보 가져오기
    • 날씨 정보 구하기
      • 읍/면/동 x, y 좌표정보를 바탕으로 다음 URL을 통해 xml 형식의 날씨 정보를 구한다.
      • "http://www.kma.go.kr/wid/queryDFS.jsp?gridx=" + leafX + "&gridy=" + leafY
      • 인천광역시 연수구 동춘2동의 날씨 구하기
        예) http://www.kma.go.kr/wid/queryDFS.jsp?gridx=55&gridy=123

        <wid><header><tm>201808140800</tm><ts>2</ts><x>55</x><y>123</y></header><body><data seq="0"><hour>12</hour><day>0</day><temp>35.0</temp><tmx>35.0</tmx><tmn>-999.0</tmn><sky>3</sky><pty>0</pty><wfKor>구름 많음</wfKor><wfEn>Mostly Cloudy</wfEn><pop>20</pop><r12>0.0</r12><s12>0.0</s12><ws>2.5</ws><wd>6</wd><wdKor>서</wdKor><wdEn>W</wdEn><reh>60</reh><r06>0.0</r06><s06>0.0</s06></data><data seq="1"><hour>15</hour><day>0</day><temp>35.0</temp><tmx>35.0</tmx><tmn>-999.0</tmn><sky>3</sky><pty>0</pty><wfKor>구름 많음</wfKor><wfEn>Mostly Cloudy</wfEn><pop>20</pop><r12>0.0</r12><s12>0.0</s12><ws>2.8000000000000003</ws><wd>7</wd><wdKor>북서</wdKor><wdEn>NW</wdEn><reh>50</reh><r06>0.0</r06><s06>0.0</s06></data><data seq="2"><hour>18</hour><day>0</day><temp>34.0</temp><tmx>35.0</tmx><tmn>-999.0</tmn><sky>3</sky><pty>0</pty><wfKor>구름 많음</wfKor><wfEn>Mostly Cloudy</wfEn><pop>20</pop><r12>0.0</r12><s12>0.0</s12><ws>2.5</ws><wd>7</wd><wdKor>북서</wdKor><wdEn>NW</wdEn><reh>55</reh><r06>0.0</r06><s06>0.0</s06></data><data seq="3"><hour>21</hour><day>0</day><temp>31.0</temp><tmx>35.0</tmx><tmn>-999.0</tmn><sky>3</sky><pty>0</pty><wfKor>구름 많음</wfKor><wfEn>Mostly Cloudy</wfEn><pop>20</pop><r12>0.0</r12><s12>0.0</s12><ws>2.3000000000000003</ws><wd>0</wd><wdKor>북</wdKor><wdEn>N</wdEn><reh>75</reh><r06>0.0</r06><s06>0.0</s06></data><data seq="4"><hour>24</hour><day>0</day><temp>29.0</temp><tmx>35.0</tmx><tmn>-999.0</tmn><sky>3</sky><pty>0</pty><wfKor>구름 많음</wfKor><wfEn>Mostly Cloudy</wfEn><pop>20</pop><r12>0.0</r12><s12>0.0</s12><ws>1.4000000000000001</ws><wd>0</wd><wdKor>북</wdKor><wdEn>N</wdEn><reh>85</reh><r06>0.0</r06><s06>0.0</s06></data><data seq="5"><hour>3</hour><day>1</day><temp>28.0</temp><tmx>35.0</tmx><tmn>28.0</tmn><sky>3</sky><pty>0</pty><wfKor>구름 많음</wfKor><wfEn>Mostly Cloudy</wfEn><pop>20</pop><r12>0.0</r12><s12>0.0</s12><ws>1.6</ws><wd>0</wd><wdKor>북</wdKor><wdEn>N</wdEn><reh>85</reh><r06>0.0</r06><s06>0.0</s06></data><data seq="6"><hour>6</hour><day>1</day><temp>28.0</temp><tmx>35.0</tmx><tmn>28.0</tmn><sky>3</sky><pty>0</pty><wfKor>구름 많음</wfKor><wfEn>Mostly Cloudy</wfEn><pop>20</pop><r12>0.0</r12><s12>0.0</s12><ws>2.2</ws><wd>0</wd><wdKor>북</wdKor><wdEn>N</wdEn><reh>85</reh><r06>0.0</r06><s06>0.0</s06></data><data seq="7"><hour>9</hour><day>1</day><temp>32.0</temp><tmx>35.0</tmx><tmn>28.0</tmn><sky>3</sky><pty>0</pty><wfKor>구름 많음</wfKor><wfEn>Mostly Cloudy</wfEn><pop>20</pop><r12>0.0</r12><s12>0.0</s12><ws>1.6</ws><wd>1</wd><wdKor>북동</wdKor><wdEn>NE</wdEn><reh>70</reh><r06>0.0</r06><s06>0.0</s06></data><data seq="8"><hour>12</hour><day>1</day><temp>35.0</temp><tmx>35.0</tmx><tmn>28.0</tmn><sky>3</sky><pty>0</pty><wfKor>구름 많음</wfKor><wfEn>Mostly Cloudy</wfEn><pop>20</pop><r12>0.0</r12><s12>0.0</s12><ws>1.5</ws><wd>4</wd><wdKor>남</wdKor><wdEn>S</wdEn><reh>55</reh><r06>0.0</r06><s06>0.0</s06></data><data seq="9"><hour>15</hour><day>1</day><temp>36.0</temp><tmx>35.0</tmx><tmn>28.0</tmn><sky>3</sky><pty>0</pty><wfKor>구름 많음</wfKor><wfEn>Mostly Cloudy</wfEn><pop>20</pop><r12>0.0</r12><s12>0.0</s12><ws>2.6</ws><wd>6</wd><wdKor>서</wdKor><wdEn>W</wdEn><reh>55</reh><r06>0.0</r06><s06>0.0</s06></data><data seq="10"><hour>18</hour><day>1</day><temp>33.0</temp><tmx>35.0</tmx><tmn>28.0</tmn><sky>3</sky><pty>0</pty><wfKor>구름 많음</wfKor><wfEn>Mostly Cloudy</wfEn><pop>20</pop><r12>0.0</r12><s12>0.0</s12><ws>1.7000000000000002</ws><wd>6</wd><wdKor>서</wdKor><wdEn>W</wdEn><reh>55</reh><r06>0.0</r06><s06>0.0</s06></data><data seq="11"><hour>21</hour><day>1</day><temp>30.0</temp><tmx>35.0</tmx><tmn>28.0</tmn><sky>3</sky><pty>0</pty><wfKor>구름 많음</wfKor><wfEn>Mostly Cloudy</wfEn><pop>20</pop><r12>0.0</r12><s12>0.0</s12><ws>2.0</ws><wd>6</wd><wdKor>서</wdKor><wdEn>W</wdEn><reh>75</reh><r06>0.0</r06><s06>0.0</s06></data><data seq="12"><hour>24</hour><day>1</day><temp>28.0</temp><tmx>35.0</tmx><tmn>28.0</tmn><sky>3</sky><pty>0</pty><wfKor>구름 많음</wfKor><wfEn>Mostly Cloudy</wfEn><pop>20</pop><r12>0.0</r12><s12>0.0</s12><ws>1.6</ws><wd>6</wd><wdKor>서</wdKor><wdEn>W</wdEn><reh>85</reh><r06>0.0</r06><s06>0.0</s06></data><data seq="13"><hour>3</hour><day>2</day><temp>27.0</temp><tmx>-999.0</tmx><tmn>26.0</tmn><sky>3</sky><pty>0</pty><wfKor>구름 많음</wfKor><wfEn>Mostly Cloudy</wfEn><pop>20</pop><r12>0.0</r12><s12>0.0</s12><ws>2.4000000000000004</ws><wd>0</wd><wdKor>북</wdKor><wdEn>N</wdEn><reh>85</reh><r06>0.0</r06><s06>0.0</s06></data><data seq="14"><hour>6</hour><day>2</day><temp>27.0</temp><tmx>-999.0</tmx><tmn>26.0</tmn><sky>3</sky><pty>0</pty><wfKor>구름 많음</wfKor><wfEn>Mostly Cloudy</wfEn><pop>20</pop><r12>0.0</r12><s12>0.0</s12><ws>1.9000000000000001</ws><wd>7</wd><wdKor>북서</wdKor><wdEn>NW</wdEn><reh>80</reh><r06>0.0</r06><s06>0.0</s06></data><data seq="15"><hour>9</hour><day>2</day><temp>30.0</temp><tmx>-999.0</tmx><tmn>26.0</tmn><sky>3</sky><pty>0</pty><wfKor>구름 많음</wfKor><wfEn>Mostly Cloudy</wfEn><pop>20</pop><r12>0.0</r12><s12>0.0</s12><ws>4.0</ws><wd>7</wd><wdKor>북서</wdKor><wdEn>NW</wdEn><reh>60</reh><r06>0.0</r06><s06>0.0</s06></data><data seq="16"><hour>12</hour><day>2</day><temp>33.0</temp><tmx>-999.0</tmx><tmn>26.0</tmn><sky>2</sky><pty>0</pty><wfKor>구름 조금</wfKor><wfEn>Partly Cloudy</wfEn><pop>10</pop><r12>0.0</r12><s12>0.0</s12><ws>5.0</ws><wd>6</wd><wdKor>서</wdKor><wdEn>W</wdEn><reh>45</reh><r06>0.0</r06><s06>0.0</s06></data></body></wid>

Python으로 해당 정보 가져오기
    • requests, beautifulSoup 사용
    • python 3 사용
    • 소스 코드
      #encoding=utf-8
      import requests
      from bs4 import BeautifulSoup
      from urllib.request import urlopen
      import os
      import json
      
      # 매개변수 URL의 JSON을 Dictionary 데이터로 return 한다.
      def getDict(url):
          print(url)
          req = requests.get(url)
          req.encoding = 'utf-8'
          rDict = json.loads(req.text)
          print(rDict)
          return rDict
      
      # Dictionary 데이터의 value 값을 List 데이터로 return 한다.
      def getList(dict):
          rList = []
          for d in topDict:
              rList.append(d['value'])
          print(rList)
          return rList
      
      # 도/시 정보 구하기.
      url = "http://www.kma.go.kr/DFSROOT/POINT/DATA/top.json.txt"
      topDict = getDict(url)
      # 도/시 정보의 value 값만 출력. 추후 combobox에 사용하기 위해서.
      topList = getList(topDict)
      # 특정 도/시의 code 정보 찾기.
      top = '인천광역시'
      for d in topDict:
          if top == d['value']:
              topCode = d['code']
              break
      print(topCode)
      
      # 시/군/구 정보 구하기.
      url = "http://www.kma.go.kr/DFSROOT/POINT/DATA/mdl." + topCode + ".json.txt"
      mdlDict = getDict(url)
      # 시/군/구 정보의 value 값만 출력.
      mdlList = getList(mdlDict)
      # 특정 시/군/구의 code 정보 찾기.
      mdl = '연수구'
      for d in mdlDict:
          if mdl == d['value']:
              mdlCode = d['code']
              break
      print(mdlCode)
      
      # 읍/면/동 정보 구하기.
      url = "http://www.kma.go.kr/DFSROOT/POINT/DATA/leaf." + mdlCode + ".json.txt"
      leafDict = getDict(url)
      # 읍/면/동 정보의 value 값만 출력.
      leafList = getList(leafDict)
      # 특정 읍/면/동의 code, x, y 정보 찾기.
      leaf = '동춘2동'
      for d in leafDict:
          if leaf == d['value']:
              leafCode = d['code']
              leafX = d['x']
              leafY = d['y']
              break
      print(leafCode)
      
      # 동네예보 (x, y 값 사용)
      # http://www.kma.go.kr/images/weather/lifenindustry/timeseries_XML.pdf
      url = "http://www.kma.go.kr/wid/queryDFS.jsp?gridx=" + leafX + "&gridy=" + leafY
      print(url)
      req = requests.get(url)
      req.encoding = 'utf-8'
      leafData = req.text
      # print(leafData)
      
      # 동네예보 (code 값 사용)
      url = "http://www.kma.go.kr/wid/queryDFSRSS.jsp?zone=" + leafCode
      print(url)
      f = urlopen(url)
      soup = BeautifulSoup(f.read(), 'xml')
      f.close()
      
      # 날씨 예보 구하기
      # 하늘상태코드
      # 1: 맑음, 2: 구름조금, 3: 구름많음, 4: 흐림
      now = soup.find_all('data')[0].sky.string
      print("하늘상태코드: " + now)
      now = soup.find_all('data')[0].wfKor.string
      print("날씨한국어: " + now)
      now = soup.find_all('data')[0].wdKor.string
      print("풍향한국어: " + now + "풍")
      
    • 결과값
      http://www.kma.go.kr/DFSROOT/POINT/DATA/top.json.txt
      [{'value': '서울특별시', 'code': '11'}, {'value': '부산광역시', 'code': '26'}, {'value': '대구광역시', 'code': '27'}, {'value': '인천광역시', 'code': '28'}, {'value': '광주광역시', 'code': '29'}, {'value': '대전광역시', 'code': '30'}, {'value': '울산광역시', 'code': '31'}, {'value': '경기도', 'code': '41'}, {'value': '강원도', 'code': '42'}, {'value': '충청북도', 'code': '43'}, {'value': '충청남도', 'code': '44'}, {'value': '전라북도', 'code': '45'}, {'value': '전라남도', 'code': '46'}, {'value': '경상북도', 'code': '47'}, {'value': '경상남도', 'code': '48'}, {'value': '제주특별자치도', 'code': '50'}]
      ['서울특별시', '부산광역시', '대구광역시', '인천광역시', '광주광역시', '대전광역시', '울산광역시', '경기도', '강원도', '충청북도', '충청남도', '전라북도', '전라남도', '경상북도', '경상남도', '제주특별자치도']
      28
      http://www.kma.go.kr/DFSROOT/POINT/DATA/mdl.28.json.txt
      [{'value': '중구', 'code': '28110'}, {'value': '동구', 'code': '28140'}, {'value': '남구', 'code': '28170'}, {'value': '연수구', 'code': '28185'}, {'value': '남동구', 'code': '28200'}, {'value': '부평구', 'code': '28237'}, {'value': '계양구', 'code': '28245'}, {'value': '서구', 'code': '28260'}, {'value': '강화군', 'code': '28710'}, {'value': '옹진군', 'code': '28720'}]
      ['서울특별시', '부산광역시', '대구광역시', '인천광역시', '광주광역시', '대전광역시', '울산광역시', '경기도', '강원도', '충청북도', '충청남도', '전라북도', '전라남도', '경상북도', '경상남도', '제주특별자치도']
      28185
      http://www.kma.go.kr/DFSROOT/POINT/DATA/leaf.28185.json.txt
      [{'value': '옥련1동', 'x': '54', 'code': '2818563000', 'y': '124'}, {'value': '옥련2동', 'x': '54', 'code': '2818564000', 'y': '124'}, {'value': '선학동', 'x': '55', 'code': '2818575000', 'y': '123'}, {'value': '연수1동', 'x': '55', 'code': '2818576100', 'y': '123'}, {'value': '연수2동', 'x': '55', 'code': '2818576200', 'y': '123'}, {'value': '연수3동', 'x': '55', 'code': '2818576300', 'y': '123'}, {'value': '청학동', 'x': '55', 'code': '2818576600', 'y': '124'}, {'value': '동춘1동', 'x': '55', 'code': '2818578000', 'y': '123'}, {'value': '동춘2동', 'x': '55', 'code': '2818579000', 'y': '123'}, {'value': '동춘3동', 'x': '55', 'code': '2818579500', 'y': '123'}, {'value': '송도동', 'x': '54', 'code': '2818581000', 'y': '123'}]
      ['서울특별시', '부산광역시', '대구광역시', '인천광역시', '광주광역시', '대전광역시', '울산광역시', '경기도', '강원도', '충청북도', '충청남도', '전라북도', '전라남도', '경상북도', '경상남도', '제주특별자치도']
      2818579000
      http://www.kma.go.kr/wid/queryDFS.jsp?gridx=55&gridy=123
      http://www.kma.go.kr/wid/queryDFSRSS.jsp?zone=2818579000
      하늘상태코드: 2
      날씨한국어: 구름 조금
      풍향한국어: 동풍
      


728x90

댓글