API : Application Programming Interface, 응용 프로그램 프로그래밍 인터페이스. 응용 프로그램에서 사용할 수 있도록 운영체제나 프로그래밍 언어가 제공하는 기능을 제어할 수 있게 만든 인터페이스
웹 API : 웹 애플리케이션 개발에서 다른 서비스에 요청을 보내고 응답을 받기 위해 정의된 명세
REST API : Representational State Transfer API, 이미 존재하고 있는 데이터를 공유하는 데 이용되며, 데이터 요청 및 응답 후에 연결이 끊어진다. (대표적)
Streaming API : 향후 발생할 이벤트에 대해 등록해 놓고 그 이벤트가 발생하면 데이터를 갱신한 후에 응답하며, 응답 이후에도 강제로 연결을 끊기 전까지는 연결을 유지한다.
인증이 필요한 웹 API : OAuth 인증 방식 (외부에서 해당 서비스에 접속하는 모바일, 데스크톱, 웹 애플리케이션의 보안 인증을 허용하는 개방형 인증 규약)으로, API 키와 접속 토큰, 그리고 비밀번호를 이용해 애플리케이션별로 인증을 수행하고 서비스를 이용할 수 있는 권한을 얻는다.
JSON, XML
JSON (JavaScript Object Notation) :
{객체}이름(name):값(value)으로 이뤄진 쌍의 집합JSON 내장 라이브러리 : JSON 형식의 데이터, 파이썬의 데이터 타입으로 쌍방 변환하는 기능json.dumps(python_data [, indent=n, sort_keys=T/F, ensure_ascii=T/F) : 파이썬 데이터를 JSON 형태로 변환json.loads(json_data) : JSON 형태의 데이터를 파이썬 데이터 타입으로 변환import json
python_dict = {'name': '홍길동', 'age': 20, 'etc': {'키':170, '몸무게':70}}
# 1. 파이썬 데이터를 JSON 형태로 변환하기
json_data = json.dumps(python_dict)
type(json_data) # str : JSON 형태의 데이터로 반환되었기 때문에 딕셔너리 데이터가 문자열로 바뀜
# 하지만 위의 방법은 출력 시 알아보기 힘드므로, 아래처럼 입력해야 한다.
json.dumps(python_dict, indent=3, sort_keys=True, ensure_ascii=False)
# 2. JSON 형태의 데이터를 파이썬 데이터 타입으로 변환하기
json_dict = json.loads(json_data)
type(json_dict) # dict
# 원하는 정보만 추출할 수도 있다.
json_dict['etc']['키'] # 170
XML (Extensible Markup Language) :
<문자열 name='속성'> : 태그에는 속성을 사용할 수 있다.<!—주석—> 존재<?xml version='1.0' encoding='UTF-8' ?><?xml version='1.0' encoding='UTF-8' ?>
<사용자 정보><이름>홍길동</이름><나이>20</나이>
<etc><키 unit='cm'>170</키><몸무게 unit='kg' >70</몸무게>
</etc></사용자정보>
xmltodic 라이브러리 (참고)xmltodict.parse(xml_input [, xml_attribs=T/F) - XML형식의 데이터를 파이썬의 딕셔너리 타입으로 변환변수[tag]['@name'] 형식으로 속성을, 변수[tag]['#text'] 형식으로 속성을 갖는 태그의 문자열을 가져온다.import xmltodict
dict_data = xmltodict.parse(xml_data, xml_attribs=Ture)
dict_data['사용자 정보']['이름'] # '홍길동'
dict_data['사용자 정보']['etc']['키']['@unit'] # cm
dict_data['사용자 정보']['etc']['키']['#text'] # ' 170'
dict_data = xmltodict.parse(xml_data, xml_attribs=False)
# True일 때와 달리, unit 등의 정보가 없다. 즉, 속성을 무시한다.
1) 웹 사이트 주소에 경로 추가하기
import requests
base_url = "https://api.github.com/"
sub_dirs = ["events", "user", "emails"]
for sub_dir in sub_dirs :
url_dir = base_url + sub_dir
r = requests.get(url_dir)
print(r.url)
>>> https://api.github.com/events
https://api.github.com/user
https://api.github.com/emails
2) 웹 사이트 주소에 매개변수 추가하기
웹 사이트 주소/경로 ? key = value & key2 = value2# 키와 값이 포함된 URL 직접 생성
import requests
LAT = "37.57" # 위도
LON = "126.98" # 경도
API_KEY = "abu94sbd" # API 키 (임의의 값)
UNIT = "metric" # 단위
site_url = "http://api.openweathermap.org/data/2.5/weather"
parameter = "?lat=%s&lon=%s&appid=%s&units=%s"%(LAT, LON, API_KEY, UNIT)
url_para = site_url + parameter
r = requests.get(url_para)
print(r.url)
>>> http://api.openweathermap.org/data/2.5/weather?lat=37.57&lon=126.98&appid=abu94sbd&units=metric
# params 인자를 사용해 딕셔너리 타입으로 키와 값을 전달하기
import requests
LAT = "37.57" # 위도
LON = "126.98" # 경도
API_KEY = "abu94sbd" # API 키 (임의의 값)
UNIT = "metric" # 단위
req_url = "http://api.openweathermap.org/data/2.5/weather"
req_parameter= {‘lat’: LAT, ‘lon’: LON, ‘appid’: API_KEY, ‘units’: UNIT}
r = requests.get(req_url, params=req_parameter)
print(r.url)
>>> http://api.openweathermap.org/data/2.5/weather?lat=37.57&lon=126.98&appid=abu94sbd&units=metric
요청 주소(url)와 요청 매개변수(params)를 분리해 requests.get()에 입력할 때, URL 인코딩(=퍼센트 인코딩)을 주의해야 한다.
디코딩이 필요하다. (requests.utils.unquote() 이용)import requests
API_KEY = "fwui3nkf%3D%3D"
API_KEY_decode = requests.utils.unquote(API_KEY)
print(API_KEY)
print(API_KEY_decode)
>>> fwui3nkf%3D%3D
fwui3nkf==
# %2B -> +, %2F -> /, %3D -> =
# (예제) 국제 우주 정거장 위치 보기
import requests
import json
url = "http://api.open-notify.org/iss-now.json"
r = requests.get(url)
json_to_dict = r.json()
print(r.text)
json_to_dict
>>> {"timestamp": 1696842653, "message": "success", "iss_position": {"longitude": "-8.6222", "latitude": "27.1186"}}
# iss_position은 각각 현재 위도, 현재 경도를 나타낸다.
def ISS_Position(iss_position_api_url) :
json_to_dict = requests.get(iss_position_api_url).json()
reruen json_to_dict['iss_position']
for k in range(5) :
print(ISS_Position(url))
tim.sleep(10) # 10초 동안 코드 실행을 일시적으로 중단
# 10초 간격으로 국제 우주 정거장의 위치 정보를 갱신한다.
# (예제) 국가 정보 가져오기
import requests
url_temp = 'https://restcountries.eu/rest/v1/name/'
country = 'South Korea'
url = url_temp + country
r = requests.get(url)
json_to_list = requests.get(url).json()
json_to_list[0]['capital']
API 키 및 접속 토큰 생성
Twitter Apps에 접속하여 애플리케이션 생성Tweepy 설치 및 인증
import tweepy
consumer_key = 'ac24asc'
consumer_secret = 'v23kjs'
access_token = '523s8fsk'
access_secret = '3fskb34'
# 트위터 API 요청 횟수 제한 : 15분 안에 최대 15개 요청 가능
auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_token, access_secret)
api = tweepy.API(auth)
API.me() # 트위터 API 사용을 위해 인증된 트위터 사용자의 다양한 정보 반환
API.me().name # 회원 등록할 때 입력한 이름 출력
# 트윗 작성하기
tweet_update_status = api.update_status('파이썬에서 트위터에 트윗 올리기')
tweet_media_update_status = api.update_with_media('C:/data/img.png', '부가적인 메시지 입력')
# 타임라인에서 메시지 가져오기
for status in tweepy.Cursor(api.home_timeline).items(2) :
print(status._json['text']) # 트위터 내용 출력
print(statue._json['created_at']) # 메시지 생성 시간 출력
# 키워드를 지정해 데이터 가져오기 (Stream API 이용)
# 인증된 auth 변수를 이용해 트위터 API 클래스 정의
class MyStreamListener(tweepy.StreamListener) :
def __init__(self, max_num) :
super().__init__()
self.tweet_num = 0
self.max_num = max_num
def on_statue(self, status) :
self.tweet_num = self.tweet_num + 1
file_name = 'C:/data/twitter_stream.txt'
if(self.tweet_num <= self.max_num) :
with open(file_name, 'a' encoding='utf-8') as f:
write_text = “***” + status.text + '\n'
f.write(write_text)
return True
else :
return False
def on_error(self, status) :
print(status)
return False
if __name__ = '__main__' :
myStreamListener = MyStreamListener(5)
myStream = tweepy.Stream(auth, myStreamListener)
myStream.filter(track = ['머신 러닝', 'Machine Learning'])
공공 데이터 포털 -> 데이터 셋 -> 오픈 API -> 원하는 서비스 선택 -> 서비스 활용 신청 -> 개발 계정 신청
# 주소 및 우편번호 가져오기 (도로명주소조회서비스)
import requests
import xmltodict
API_KEY = 'apikey'
API_KEY_decode = requests.utils.unquote(API_KEY)
req_url = 'http://openapi.epost.go.kr/postal/retrieveNewAdressAreaCdService/retrieveNewAdressAreaCdService/getNewAddressListAreaCd'
search_Se = 'road'
srch_wrd = '반포대로 201'
req_parameter = {'ServiceKey':API_KEY_decode, 'searchSe':search_Se, 'srchwrd':srch_wrd}
r = requests.get(req_url, params = req_parameter)
xml_data = r.text
dict_data = xmltodict.parse(xml_data)
adress_list = dict_data['NewAddressListResponse']['newAddressListAreaCd']
print(adress_list['zipNo']) # 우편번호
print(adress_list['lnmAdres']) # 도로명 주소
print(adress_list['rnAdres']) # 지번 주소
# 날씨 정보 가져오기 (동네예보정보조회서비스)
import json
import datetime
now = datetime.datetime.now()
date = "{:%Y%m%d}”.format(now)
time = "{:%H00}".format(now)
req_url = "http://newsky2.kma.go.kr/service/SecndSrtpdFrcstInfoService2/ForecastGrib"
baseDate, baseTime = date, time # 발표 일자, 시간 지정
nx_val, ny_val = 60, 127 # 예보지점 좌표 (서울시 종로구 사직동)
num_of_rows = 6 # 한 페이지에 포함된 결과 수
page_no = 1 # 페이지 번호
output_type = "json" # 응답 데이터 형식 지정
req_parameter = {"ServiceKey":API_KEY_decode, "nx":nx_val, "ny":ny_val, "base_date":baseDate, "base_time":baseTime, "pageNo":page_no, "num0fRows":num_of_rows, "_type":output_type}
r = requests.get(req_url, params = req_parameter) # 데이터 요청
dic_data = r.json() # JSON 형태로 받은 데이터를 딕셔너리 데이터로 변환
weather_items = dict_data['response']['body']['items']['item']
sky_cond = ['맑음', '구름 조금', '구름 많음', '흐림']
rain_type = ['없음', '비', '진눈개비', '눈']
print("발표 날짜 : {}".format(weather_items[0]['baseDate']))
for k in range(len(weather_items)) :
weather_item = weather_items[k]
obsrValue = weather_item['obsrValue']
if(weather_item['category'] == 'T1H') :
print('기온 : {}도'.format(obsrValue))
elif(weather_item['category'] == 'REH') :
print('습도 : {}%'.format(obsrValue))
elif(weather_item['category'] == 'SKY') :
print('하늘 : {}%'.format(sky_cond[obsrValue-1]))
elif(weather_item['category'] == 'PTY') :
print('강수 : {}'.format(rain_type[obsrValue]))
참고 :
데이터 분석을 위한 파이썬 철저 입문