API ์์ฒญ
owlbot์ด ์ ๊ณตํด์ฃผ๋ token์ api-key๊ฐ์ผ๋ก ํ์ฌ ๋จ์ด๋ฅผ ๊ฒฝ๋ก๋ณ์๋ก ์ ๋ฌํ๋ฉด ํด๋น ๋จ์ด์ ์ฌ๋ฌ ์ ๋ณด๋ฅผ ์ ๊ณตํด์ค๋ค.
(๋จ์ด์ด๋ฆ, ์๋ฆฌ, ํ์ฌ,์๋ฌธ,์ด๋ฏธ์ง ...)
API ์์ฒญ ๊ฒฐ๊ณผ ์์
{
"word": "owl",
"pronunciation": "oul",
"definitions": [
{
"type": "noun",
"definition": "a nocturnal bird of prey with large eyes, a facial disc, a hooked beak, and typically a loud hooting call.",
"example": "I love reaching out into that absolute silence, when you can hear the owl or the wind.",
"image_url": "https://media.owlbot.info/dictionary/images/hhhhhhhhhhhhhhhhhhhu.jpg.400x400_q85_box-15,0,209,194_crop_detail.jpg",
"emoji": "๐ฆ"
}
]
}
api ์์ฒญ fstring
์ ์ด์ฉํด์ ํด๋ผ์ด์ธํธ๋ก๋ถํฐ ๋ฐ์ ๋ฌธ์๋ฅผ ๊ฒฝ๋ก๋ณ์๋ก ํ๊ณ ๋ฐ๊ธ๋ฐ์ ํ ํฐ์ ํค๋์ ๊ตฌ์ฑํด์ api์๋ฒ๋ก ์์ฒญํ๋ค.
flask ๊ฒฝ๋ก๋ณ์ ์ฌ์ฉ๋ฒ
@app.route('/test/<param>') def test(param):
์์ฒญ ํ ๋ฐ์ ๊ฒฐ๊ณผ๋ json์ผ๋ก ๋ณํ ํ ํด๋ผ์ด์ธํธ์๊ฒ ์ ๋ฌํ๋ค.
r = requests.get(f'https://owlbot.info/api/v4/dictionary/{keyword}',
headers={'Authorization' : f'Token {owlApiKey}'})
result = r.json()
๊นํ์ ์์ค์ฝ๋๋ฅผ ์ฌ๋ฆฌ๊ณ ์ถ๋ค๋ฉด??
key(token) ์จ๊ธฐ๊ธฐ (xml๋ก key ๋ฆฌ์์ค ์์ฑ)
[keys.xml]
<?xml version="1.0" encoding="utf-8" ?>
<resource>
<string name="owlbot-key">[my-apikey]</string>
</resource>
xml๋ก ์์ฑ๋ ๋ฆฌ์์ค ๊ฐ์ ธ์ค๊ธฐ
import xml.etree.ElementTree as et
tree = et.parse('keys.xml')
owlApiKey = tree.find('string[@name="owlbot-key"]').text
.gitignore
์ keys.xml
์ค์
{
"word": "owl",
"pronunciation": "oul",
"definitions": [
{
"type": "noun",
"definition": "a nocturnal bird of prey with large eyes, a facial disc, a hooked beak, and typically a loud hooting call.",
"example": "I love reaching out into that absolute silence, when you can hear the owl or the wind.",
"image_url": "https://media.owlbot.info/dictionary/images/hhhhhhhhhhhhhhhhhhhu.jpg.400x400_q85_box-15,0,209,194_crop_detail.jpg",
"emoji": "๐ฆ"
}
]
}
ํด๋ผ์ด์ธํธ๋ ๋จ์ด๋ฅผ ์์ฒญํ๋ฉด ์๋ฒ๋ก๋ถํฐ ์์ ๊ฐ์ jsonํฌ๋ฉง ๋ฐ์ดํฐ๋ฅผ ๋ฐ๋๋ค.
๋ฐ์ jsonํฌ๋ฉง ๋ฐ์ดํฐ๋ฅผ HTML์ ๋ง์ถฐ ๋ผ์์ค์ผ ํ๋๋ฐ ์ด๋ jinja2
ํ
ํ๋ฆฟ์ ์ฌ์ฉํ๋ค.
jinja2 ํ ํ๋ฆฟ ๊ฐ๋จ ๋ฌธ๋ฒ
๊ฐํํ: {{ }}
ํ๋ณํ: {{ a|int }} (a๋ฅผ ์ ์๋ก ๋ณํ)
if๋ฌธ : {% if a>=0 %} ... {% endif %}
for๋ฌธ : {% for row in rows %} ... {% endfor %}
ํ์ด์ฐธ jinja2 ํ ํ๋ฆฟ ์ค์ (mac)
[perference]-[Template Languages]-HTML์ Jinja2๋ก ์ค์
์๋ฒ๋ก๋ถํฐ result
๋ผ๋ key๊ฐ์ผ๋ก api์ ์๋ต์ ๋ํ ์๋ต์ด ๋ด๋ ค์๋ค๋ฉด {{ result['word'] }}
or {{ result.word }}
์ ๊ฐ์ ๋ฐฉ์์ผ๋ก ๊ฐ์ ๋ํ๋ผ ์ ์๋ค.
๋ค์ด๋ฒ ํด๋ผ์ฐ๋ ํ๋ซํผ์ ์ฝ์๋ก ์ด๋
์ ํ๋ฆฌ์ผ์ด์
๋ฑ๋ก
์ ํ๋ฆฌ์ผ์ด์
์ด๋ฆ ์ง์ ํ Web Dynamic Map
, Geocoding
์ ํ,
์๋น์ค ํ๊ฒฝ ๋ฑ๋ก - web ์๋น์ค URL ๋ฑ๋ก
๋ฑ๋ก ํ ์ธ์ฆ์ ๋ณด ํ์ธ
Client ID
(X-NCP-APIGW-API-KEY-ID)
Client Secret
(X-NCP-APIGW-API-KEY)
htmlํ์ผ์ API ์์ฒญ ์คํฌ๋ฆฝํธ ์ถ๊ฐ
<script type="text/javascript"
src="https://openapi.map.naver.com/openapi/v3/maps.js?ncpClientId=[ํด๋ผ์ด์ธํธID]"></script>
naver-map ์ค๋ธ์ ํธ๋ฅผ ์์ฑํ๋ ํจ์ ์ ์
$(document).ready(function () {
let mymap = new naver.maps.Map('map', {
center: new naver.maps.LatLng(์๋, ๊ฒฝ๋),
zoom: 10,
zoomControl: true,
zoomControlOptions: {
style: naver.maps.ZoomControlStyle.SMALL,
position: naver.maps.Position.TOP_RIGHT
}
});
center
: ์ง๋์ ์์ ์๋,๊ฒฝ๋ ์ง์
zoom
: ์ง๋ ์์์ ์ค ๋ฐฐ์จ ์ง์
zoomControl
: ์ค ์กฐ์ ๋ฒํผ ํ์ฑํ
zoomControlOptions
: ์ค ์กฐ์ ๋ฒํผ ์คํ์ผ ์ค์
marker ์ถ๊ฐ
let marker = new naver.maps.Marker({
position: new naver.maps.LatLng(์๋, ๊ฒฝ๋),
map: mymap,
icon: "{{ url_for('static', filename='image.png') }}" // ๋ง์ปค ์ด๋ฏธ์ง
});
position
: ๋ง์ปค์ ์์ ์๋,๊ฒฝ๋ ์ง์
map
: ํด๋น ๋ง์ปค๊ฐ ํ์๋ map ์ง์
icon
: ๋ง์ปค์ icon ์ง์
infowindow ์ถ๊ฐ
infowindow: ๋ง์ปค ํด๋ฆญ์ ๋ํ๋๋ ์ฐฝ
let infowindow = new naver.maps.InfoWindow({
content: `<div><h5>infoWindow content</h5></div>`,
});
marker์ ์ด๋ฒคํธ ์ถ๊ฐ (ํด๋ฆญ์ infowindow ์ด๊ธฐ/๋ซ๊ธฐ)
naver.maps.Event.addListener(marker, "click", function () { // marker ํด๋ฆญ์ ์ด๋ฒคํธ ์ง์
if (infowindow.getMap()) { // infowindow๊ฐ ์ด๋ ค์๋ค๋ฉด true
infowindow.close(); // ์ด๋ ค์๋ค๋ฉด (true๋ผ๋ฉด) close
} else {
infowindow.open(map, marker);
}
});
Geocoding api
๋ ์ฃผ์๋ฅผ ์
๋ ฅ๋ฐ์ ํด๋น ์ฃผ์์ ์์ธ์ ๋ณด๋ฅผ ์ ๊ณตํด์ฃผ๋ API์ด๋ค.
์๋ต ์์ Json
ํ๋ก์ ํธ์์ ํ์ํ ์ ๋ณด๋ ๊ฒฝ๋, ์๋ ์ ๋ณด์ธ x
, y
์ด๋ฏ๋ก ์์ฒญ ํ ๋ ์ ๋ณด๋ง ํ์ฑํ๋ค.
{
"status": "OK",
"meta": {
"totalCount": 1,
"page": 1,
"count": 1
},
"addresses": [
{
"roadAddress": "๊ฒฝ๊ธฐ๋ ์ฑ๋จ์ ๋ถ๋น๊ตฌ ๋ถ์ ๋ก 6 ๊ทธ๋ฆฐํฉํ ๋ฆฌ",
"jibunAddress": "๊ฒฝ๊ธฐ๋ ์ฑ๋จ์ ๋ถ๋น๊ตฌ ์ ์๋ 178-1 ๊ทธ๋ฆฐํฉํ ๋ฆฌ",
"englishAddress": "6, Buljeong-ro, Bundang-gu, Seongnam-si, Gyeonggi-do, Republic of Korea",
"addressElements": [
{
"types": [
"POSTAL_CODE"
],
"longName": "13561",
"shortName": "",
"code": ""
}
],
"x": "127.10522081658463",
"y": "37.35951219616309",
"distance": 20.925857741585514
}
],
"errorMessage": ""
}
API ์์ฒญ
address๋ ์คํฌ๋ํ์ ํตํด ์ป์ด์จ ๋ง์ง์ฃผ์๊ฐ ๋ค์ด๊ฐ๊ฒ ๋๋ค.
์ด์ ๊ณผ ๋ง์ฐฌ๊ฐ์ง๋ก API์ ์๋ต๊ฒฐ๊ณผ๋ฅผ ํ์ฑํ๊ธฐ ์ํด Json์ผ๋ก ๋ณํํ๋ค.
r = requests.get(f"https://naveropenapi.apigw.ntruss.com/map-geocode/v2/geocode?query={address}", headers=headers)
response = r.json()
API ์์ฒญํค๋ ๊ตฌ์ฑ (keyํฌํจ)
headers = {
"X-NCP-APIGW-API-KEY-ID": "[ํด๋ผ์ด์ธํธID]",
"X-NCP-APIGW-API-KEY": "[ํด๋ผ์ด์ธํธSecret]"
}
API ์๋ต ํ์ฑ
x = float(response["addresses"][0]["x"])
y = float(response["addresses"][0]["y"])
๋ ๊ฐ ํ๋ก์ ํธ๋ฅผ ํตํด open api๋ฅผ ์์ฒญํ๋ ๋ช ๊ฐ์ง ๋ฐฉ๋ฒ์ ์์๋ดค์ต๋๋ค. ์ ๋ชจ๋ฐฉํ๊ณ ์ ๊ฐ๋ค ์ฐ๋ ๊ฒ๋ ๋งค์ฐ ์ค์ํ ๊ฐ๋ฐ ๋ฅ๋ ฅ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค.
๊ทธ๋ฌ๋ ์~ ์ฐ๊ฒ ์ต๋๋ค ๐