728x90
기상청에서 제공하는 날씨 데이터는 기상자료개방포털을 통해서 csv 형태로 데이터를 얻어내는 방법이 있다. 하지만, 이 방법은 원하는 데이터를 얻어야 할 때 마다 직접 홈페이지로 들어가서 csv로 다운을 받아야 하는 번거로운 작업을 해줘야 한다.
이에 대한 대안으로 기상청 API 허브를 이용할 수 있다.
상황
1) 지상관측 데이터를 받아온다.
2) Java를 이용해서 기상청 데이터를 csv 형태로 저장하려고 한다.
3) 회원가입을 하고나서 인증키
까지 받아냈다.
URL 파악
지상관측 자료 중 기간 정해서 조회하는 URL
을 살펴보겠다. - 시간자료(기간조회)
- tm1 : 시작시간 또는 시작일 (default는 현재시간) - 형식 YYYYmmddHHMM 또는 YYYYmmdd
- tm2 : 종료시간 또는 종료일 (default는 현재시간) - 형식 YYYYmmddHHMM 또는 YYYYmmdd
- stn : 지점번호 (default는 0 또는 전체시점)
- help : 도움말 추가 여부 (1이면 도움말 추가 / 0이거나 없으면 도움말 없음)
- authKey : 발급된 API 인증키
이를 토대로 위에 있는 URL을 해석하면
지점번호 108번의 날씨 데이터 중에서 2015년 12월11일 01시 00분 ~ 2015년 12월 14일 00시 00분까지의 데이터를 도움말을 첨부해서 반환한다는 뜻이다.
해당 URL에서는 1시간 단위의 데이터를 제공한다.
데이터 예시
그렇다면, 이 데이터를 어떻게 csv로 가져올 수 있는지 살펴보겠다.
이용 방법
1. 원하는 경로에 csv 파일 지정
import java.io.BufferedWriter;
import java.io.FileWriter;
BufferedWriter bf = new BufferedWriter(new FileWriter("원하는 경로" + "/" + "원하는이름" +".csv", false));
// 결과값들을 저장할 StringBuilder
StringBuilder results = new StringBuilder();
2. URL을 통한 데이터 받아오기
import java.net.URL;
import java.net.HttpURLConnection;
import java.io.BufferedReader;
import java.io.InputStreamReader;
// 앞서 얘기한 URL이다.
// 각각의 값은 모두 String 형태로 만들어서 추가하면 된다.
// 여기서는 help가 필요없다고 판단해서 help 인수는 넣지 않았다.
URL url = new URL("https://apihub.kma.go.kr/api/typ01/url/kma_sfctm3.php?"
+ "tm1=" + "시작시간" + "&tm2=" + "종료시간"
+ "&stn=" + "지점번호" + "&authKey=" + "인증키");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET"); // 요청 메시지를 보낼 때 GET 메소드를 사용하도록 함
// http request를 통해 반환받은 데이터를 BufferedReader 자료형 변수 br에 저장
BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
3. 데이터 처리
앞서 데이터를 봤으면 알겠지만 불필요한 데이터가 존재하고 원하는 만큼 깔끔하게 데이터가 저장되는 건 아니라서
어느 정도의 후처리가 필요하다.
- 컬럼 정리
import java.util.LinkedList;
import java.util.List;
import java.util.StringTokenizer;
// 1,2번째 행을 버리기 위해서 readLine()으로 넘겨버렸다.
br.readLine(); br.readLine();
// 3번째 행 = csv로 저장할 때 각 데이터의 이름들 = 컬럼의 헤더 값
// 한 칸 띄어쓰기(" ")를 기준으로 구분되도록 StringTokenizer를 사용했다.
List columnNames = new LinkedList<>();
StringTokenizer st = new StringTokenizer(br.readLine());
st.nextToken(); // 3번째 행의 #은 버린다.
// 각각의 값을 리스트에 추가
while(st.hasMoreTokens()) columnNames.add(st.nextToken());
// 한 칸씩 띄어쓰기 된 경우도 있지만
// 2칸 이상 띄어쓰기 된 경우도 많기 때문에 아래와 같이 모든 컬럼 값들에 대해 replace를 해줘야 한다.
String columnNamesString = columnNames.toString().replace(" ", "");
results.append(columnNamesString.substring(1, columnNamesString.length() - 1) + "\\n");
// 4번째 줄은 단위값인데 굳이 필요가 없다고 판단해서 버림
br.readLine();
- 데이터 정리
String inputLine = null;
List dataList = new LinkedList<>();
// 데이터 정리
while((inputLine = br.readLine()) != null) {
// 띄어쓰기로 구분된 값을 dataList에 저장
st = new StringTokenizer(inputLine);
while(st.hasMoreTokens()) {
dataList.add(st.nextToken());
}
// dataList에 있는 모든 값을 result에 추가하고 초기화
results.append(dataList.toString().replace(" ", "").substring(1, dataList.toString().replace(" ", "").length() - 1) + "\n");
dataList = new LinkedList<>();
}
- 파일 쓰기
br.close(); bf.flush();
bf.write(results.toString());
CSV 결과 예시
'다양한 주제' 카테고리의 다른 글
Windows 배치파일 (0) | 2023.07.27 |
---|---|
Windows 작업 스케줄러 (0) | 2023.07.26 |
netstat에 대해 (0) | 2023.07.25 |
scp에 대해(정의, 사용법, 비밀번호 없이 동작하도록 하는 방법) (0) | 2023.07.25 |
crontab (0) | 2023.07.20 |