[Python] 아파트 매매 실거래가 수집하기 (feat. 국토교통부 OpenAPI)
<< 문제 정의 >>
부동산 매매데이터를 KB부동산 사이트 를 통해서 활용하는 경우가 많습니다.
그러나, 일일이 아파트를 검색하고, 매매거래가를 다운로드 받아서 활용해야 하는 불편함이 있습니다. '크롤링을 통해서 프로그램화 하면 되지 않아?' 라고 생각할 수 있지만, KB부동산의 경우 크롤링에 필요한 html 코드를 볼 수 없게 막아두었답니다.ㅠㅠ
다행히도 공공데이터(www.data.go.kr)에서는 OpenAPI를 제공해주고 있습니다. 이를 이용하여 부동산 실거래 데이터를 수집해보시죠!
<< 사전 준비 사항 >>
- 공공데이터 가입 (www.data.go.kr)
- 사용할 API: 공공데이터 포털(국토교통부 - 아파트매매 실거래데이터)
- 언어 & 환경(IDE) : Python3.6 & Jupter notebook
<< 순서 >>
Step 1 |
아파트매매 실거래 데이터 OpenAPI 신청하기 ※ OpenAPI 사용시 제공기관 연계서버와 일정시간을 주기로 동기화되며 동기화에 시간이 소요될 수 있다. |
Step 2 | OpenAPI 테스트하기 |
Step 3 | OpenAPI 파라메터 이해하기 |
Step 4 | 법정동 코드 다운로드 |
Step 5 |
구현 1) 아파트 실거래 OpenAPI 호출 2) 하드코딩한 법정동 코드값 변경하기 3) 하드코딩한 날짜값 변경하기 4) 특정 '구'를 요청 날짜만큼 실거래데이터 저장하기 |
Step1) 아파트매매 실거래자료 OpenAPI 신청하기
신청 순서 : www.data.go.kr > [부동산거래정보] 클릭 > [공공데이터보기] 클릭 > [오픈API] 클릭 > [국토교통부 실거래가 정보] 클릭 > [아파트매매 실거래자료 - 활용신청] 클릭 > [신청] 클릭
신청완료!
Step2) OpenAPI 테스트하기
2-1) 일반 인증키 란이 비어 있다면? [일반 인증키 받기]
2-2) 테스트
※ OpenAPI 사용시 제공기관 연계서버와 일정시간을 주기로 동기화되며 동기화에 시간이 소요될 수 있습니다.
참고) "아파트매매 실거래 상세 자료" API의 경우는 빨간색 박스가 추가됨.
Step3) OpenAPI 파라메터 이해하기
- "아파트매매 신고정보 조회 기술문서.hwp" 파일 다운로드 > 파라메터 확인
법정동 코드가 필요함을 알 수 있다.
Step4) 법정동 코드 다운로드
www.code.go.kr > [법정동] 선택 > [법정동 코드 전체자료] 클릭 > 법정동코드 다운로드 > 파일 포맷을 utf-8 로 변경
한글이 깨지는 경우가 있어 메모장으로 파일을 열어 "UTF-8" 포맷으로 변경하여 재저장 합니다.
Step5) 구현
Step 5-1) 아파트 실거래 OpenAPI 호출
호출시 전달해야 할 파라메터는 다음과 같습니다.
정상동작 확인을 위해서 "지역코드"와 "계약월"은 하드코딩해서 진행하겠습니다.
step5-2부터는 지역코드/계약월을 필요에 따라 설정하도록 변경하겠습니다.
# 1-1. 데이터 가져오기
import requests
import datetime
url ="http://openapi.molit.go.kr:8081/OpenAPI_ToolInstallPackage/service/rest/RTMSOBJSvc/getRTMSDataSvcAptTrade?"
service_key = "<인증키를 입력하세요> "
base_date = "202001"
gu_code = '11215' ## 법정동 코드 5자리라면, 구 단위로 데이터를 확보하는 것. 11215 = 광진구
payload = "LAWD_CD=" + gu_code + "&" + \
"DEAL_YMD=" + base_date + "&" + \
"serviceKey=" + service_key + "&"
res = requests.get(url + payload)
print(res)
200이 나오면 성공입니다.
전달된 데이터가 xml형태이므로, 라이브러리를 사용해서 parsing합니다.
결과 데이터를 dataframe 형태로 관리하도록 하겠습니다.
import xml.etree.ElementTree as ET
def get_items(response):
root = ET.fromstring(response.content)
item_list = []
for child in root.find('body').find('items'):
elements = child.findall('*')
data = {}
for element in elements:
tag = element.tag.strip()
text = element.text.strip()
# print tag, text
data[tag] = text
item_list.append(data)
return item_list
items_list = get_items(res)
items = pd.DataFrame(items_list)
items.head()
[결과 확인]
이제부터는 하드코딩한 내용을 제거하고, 파일로 저장하는 것 까지를 구현해 보시죠!!
Step5-2) 하드코딩한 법정동 코드값 변경하기
1. 다운로드 받아둔 "법정동코드 전체자료.txt" 파일 읽기
법정동 코드의 경우 tab으로 분리가 되어 있음을 알 수 있습니다.
code_file = "법정동코드 전체자료/법정동코드 전체자료.txt"
code = pd.read_csv(code_file, sep='\t')
2. 데이터 클린징
2-1. 컬럼명이 한글로 되어 있으면 코딩하기 번거로우므로 한글로 변경
code.columns = ['code', 'name', 'is_exist']
2-2. 폐지된 법정동 코드는 사용할 필요 없으므로 삭제
code = code [code['is_exist'] == '존재']
2-3. 법정동 코드가 int로 되어 있는데, string으로 변경
print(code['code'][0])
print(type(code['code'][0])) ## int64타입
## string으로 변경
code['code'] = code['code'].apply(str)
Step5-3) 하드코딩한 날짜값 변경하기
2015년 01월 ~ 2019년 12월 까지 데이터를 받아보도록 하겠습니다.
year = [str("%02d" %(y)) for y in range(2015, 2020)]
month = [str("%02d" %(m)) for m in range(1, 13)]
base_date_list = ["%s%s" %(y, m) for y in year for m in month ]
Step5-4) 특정 '구'를 요청 날짜만큼 실거래데이터 저장하기
1. "광진구"의 법정동 코드 5자리 추출
gu = "광진구"
gu_code = code[ (code['name'].str.contains(gu) )]
gu_code = gu_code['code'].reset_index(drop=True)
gu_code = str(gu_code[0])[0:5]
print(gu_code)
2. step5-1)에서 수행했던 소스코드를 함수형태로 만들어 사용
import requests
import datetime
def get_data(gu_code, base_date):
url ="http://openapi.molit.go.kr:8081/OpenAPI_ToolInstallPackage/service/rest/RTMSOBJSvc/getRTMSDataSvcAptTrade?"
service_key = "<인증키를 입력하세요>"
payload = "LAWD_CD=" + gu_code + "&" + \
"DEAL_YMD=" + base_date + "&" + \
"serviceKey=" + service_key + "&"
res = requests.get(url + payload)
return res
3. step5-3) 에서 준비해둔 날짜만큼 반복하며 실거래 데이터 얻기
items_list = []
for base_date in base_date_list:
res = get_data(gu_code, base_date)
items_list += get_items(res)
len(items_list)
총, 10,073건의 데이터를 얻었네요^^
4. dataframe 형태로 변경하여 csv파일로 저장
파일명은 [구이름]_[시작년도]_[끝년도].csv로 저장하겠습니다.
items = pd.DataFrame(items_list)
items.head()
items.to_csv(os.path.join("%s_%s~%s.csv" %(gu, year[0], year[-1])), index=False,encoding="euc-kr")
[결과 확인]
이것으로 실거래가 데이터를 가지고 오는것은 완성! 하였습니다.
다른 지역의 데이터를 가져와 저장하고 싶다면, gu = "광진구" 만 변경하면 됩니다~!!
< 참고 >
- 국토부에서 제공하는 (OpenAPI) 데이터는 전용면적을 기준으로 데이터를 제공
- 네이버 부동산, KB, 호갱노노 모두 공급면적 기준으로 데이터를 제공
저작물의 저작권은 작성자에게 있습니다.
공유는 자유롭게 하시되 댓글 남겨주세요~
상업적 용도로는 무단 사용을 금지합니다.
끝까지 읽어주셔서 감사합니다^^