>
공공데이터포털에 접속해 인증키값을 받고, 데이터를 확인해보는 과정을 해봤다.
https://marketerbong.tistory.com/99
이제, 여기서 받은 정보를 내 사이트에 적용해보자.
내가 원하는 것은 아래 이미지처럼 현재 온도이다.
기본적인 파이썬 코드는 다음과 같다.
from flask import Flask, request, jsonify
from datetime import datetime
import requests
app = Flask(__name__)
@app.route('/weather', methods=['GET'])
def get_weather():
# Retrieve current date and time
now = datetime.now()
base_date = now.strftime("%Y%m%d") # Format: YYYYMMDD
base_time = now.strftime("%H%M") # Format: HHMM (24-hour clock)
# Retrieve latitude and longitude from query parameters
nx = request.args.get('nx')
ny = request.args.get('ny')
# Check if nx and ny were provided
if not nx or not ny:
return jsonify({"error": "Latitude (nx) and Longitude (ny) are required"}), 400
# Construct the API URL with real-time parameters
api_url = f"https://apis.data.go.kr/1360000/VilageFcstInfoService_2.0/getUltraSrtNcst" \
f"?serviceKey=이건디코딩키값넣으세요" \
f"kW%2BcJaIK6g%3D%3D&pageNo=1&numOfRows=1000&dataType=json" \
f"&base_date={base_date}&base_time={base_time}&nx={nx}&ny={ny}"
# Make the request to the external API
try:
response = requests.get(api_url)
response.raise_for_status() # Check if the request was successful
data = response.json()
return jsonify(data) # Return the API response in JSON format
except requests.exceptions.RequestException as e:
return jsonify({"error": str(e)}), 500
if __name__ == '__main__':
app.run(debug=True)
근데, 저렇게 하면 안될 것이다.
왜냐하면 위치정보를 알 수 없기 때문이다.
아래의 과정이 추가로 필요하다.
1. 현재 gps 좌표 정보를 업데이트 한 후 전달하기
2. gps 좌표를 받은 후 경도/위도를 nx, ny값으로 치환하기
번외로 아래 2가지 작업도 필요하다.
3. 내 사이트는 블루프린트로 페이지를 관리한다. 그렇기에 블루프린트 처리도 해줘야한다.
4. 만약 gps 좌표를 못불러올 경우 지정 좌표로 쏴주기. (구글지도나 크롬 같은 브라우저에서 현재 위치 확인 미허용을 누른 경우에 해당)
일단 1번과 3번은 자바스크립트로 작업했기에, 2번과 4번을 반영한 스크립트를 공유한다.
1) 엑셀파일이 한글로 너무 길어서 nxny.xlsx로 파일명을 바꿔, pandas로 불러왔다 (이건 sql, 데이터 분석을 하는 마케터라면 조금 익숙할 것이다)
2) 현재 좌표에서 가까운 nx, ny를 찾는다.
3) 날씨 라우터에서 현재날짜, 현재시간, 경도, 위도를 변수로 설정하여, api 요청 url에 넣었다.
from flask import Flask, request, jsonify, Blueprint
from datetime import datetime
from geopy.distance import geodesic
import requests
import pandas as pd
# Flask 블루프린트 설정
bp = Blueprint("api_weather", __name__)
# 위치 데이터 파일 불러오기 (파일 경로 확인 필요)
location_data = pd.read_excel('static/file/nxny.xlsx')[['격자 X', '격자 Y', '경도(초/100)', '위도(초/100)']]
# 가장 가까운 격자 좌표(nx, ny) 찾는 함수
def find_nearest_grid_coordinates(latitude, longitude):
min_distance = float('inf')
nearest_nx = None
nearest_ny = None
for _, row in location_data.iterrows():
grid_point = (row['위도(초/100)'], row['경도(초/100)'])
distance = geodesic((latitude, longitude), grid_point).meters
if distance < min_distance:
min_distance = distance
nearest_nx = row['격자 X']
nearest_ny = row['격자 Y']
return nearest_nx, nearest_ny
# 날씨 API 라우트 설정
@bp.route('/', methods=['GET'])
def get_weather():
print("Received parameters:", request.args)
# 현재 날짜와 시간 가져오기
now = datetime.now()
base_date = now.strftime("%Y%m%d")
base_time = now.strftime("%H%M")
# 쿼리 파라미터에서 위도와 경도 가져오기
latitude = request.args.get('latitude')
longitude = request.args.get('longitude')
# 위도와 경도 값 검증
if latitude is None or longitude is None:
print(f"Missing parameters: latitude={latitude}, longitude={longitude}") # Debug log
return jsonify({"error": "Both latitude and longitude parameters are required"}), 400
# 위도와 경도를 float로 변환
try:
latitude = float(latitude)
longitude = float(longitude)
except ValueError:
return jsonify({"error": "Latitude and longitude must be valid numbers"}), 400
# 가장 가까운 격자 좌표 찾기
nx, ny = find_nearest_grid_coordinates(latitude, longitude)
if nx is None or ny is None:
return jsonify({"error": "Unable to find nearest grid coordinates"}), 500
# API 요청 URL 생성
api_url = (
f"https://apis.data.go.kr/1360000/VilageFcstInfoService_2.0/getUltraSrtNcst"
f"?serviceKey=디코딩키값을넣으면됩니다"
f"kW%2BcJaIK6g%3D%3D&pageNo=1&numOfRows=1000&dataType=json"
f"&base_date={base_date}&base_time={base_time}&nx={int(nx)}&ny={int(ny)}"
)
# 외부 API 호출 및 결과 반환
try:
response = requests.get(api_url)
response.raise_for_status() # HTTP 오류가 있으면 예외 발생
data = response.json()
return jsonify(data) # API 응답을 JSON 형식으로 반환
except requests.exceptions.RequestException as e:
return jsonify({"error": str(e)}), 500
일단 위와 같이 만들면 url이 생긴다.
bongdroid.info/api_weater 라는 주소로 접속하면 api_weather 페이지가 json 형태로 나올 것이다.
즉, API URL(웹API)가 만들어진 것이다.
사실 "json url 만드는 법", "api url 만드는 방법" 등으로 검색해봤는데, 안나왔다.
그러다 우연히 웹API가 내가 만들려고 했던 api url인 것 같았다. 그래서 그걸로 검색해보니 얼추 나오더라.
이제 자바스크립트로 현재 경도/위도를 가져와야한다.
아참, geopy 라는 라이브러리 설치는 말안해도 하는 센스-👏
자바스크립트 코드는 다음과 같다.
1) 페이지가 불려오자마자 실행되어야 하기때문에 document.ready로 함수를 불러왔다.
2) navigator.geolocation으로 현재 좌표를 불러오고, 실패한다면 지정한 좌표값을 불러오도록 했다.
3) 불러온 좌표값을 fetchWeatherData 함수에 각각 위도/경도를 넣도록 했다.
4) Flask API URL에 위도와 경도를 전송하도록 했다.
5) 온도를 아이디값 temp에 넣으라고 했다.
<script>
$(document).ready(function () {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(success, error);
} else {
fetchWeatherData(37.563569, 126.980008333333); // Use default coordinates
}
function success(position) {
const latitude = position.coords.latitude;
const longitude = position.coords.longitude;
fetchWeatherData(latitude, longitude);
}
function error() {
console.warn("Unable to retrieve location. Using default coordinates.");
fetchWeatherData(37.563569, 126.980008333333); // Use default coordinates
}
function fetchWeatherData(latitude, longitude) {
// Send latitude and longitude to Flask API
$.get(`/api_weather/`, { latitude: latitude, longitude: longitude })
.done(function (data) {
let temp = null;
// Loop through the items and find the "T1H" category
const items = data.response.body.items.item;
for (const item of items) {
if (item.category === "T1H") {
temp = item.obsrValue;
break;
}
}
// Display temperature or error message
if (temp !== null) {
$('#temp').text(`${temp}`);
} else {
$('#temp').text('Temperature data not available');
}
})
.fail(function () {
$('#temp').text('Error retrieving weather data');
});
}
});
</script>
기상청 날씨 api를 확인해보자!(w. 공공데이터포털) (1) | 2024.11.01 |
---|---|
티스토리 RSS 피드를 내 사이트에 가져와보자!(aka. 웹 크릴링, ft. 프록시) (0) | 2024.10.30 |
특정 등급의 회원만 접근 가능한 페이지를 만들자! (0) | 2024.10.29 |
회원 탈퇴 기능을 만들어보자! (0) | 2024.10.29 |
비밀번호 변경 기능을 만들어보자! (ft. JWT 암호화/복호화) (0) | 2024.10.28 |