최근엔 부동산이 크게 하락하고 규제들이 없어져서 관심이 없어졌지만, 취득세 중과 때문에 비규제 지역의 공시지가 1억 미만 아파트들이 각광을 받던 시절이 있었습니다. 공시지가 1억 미만 아파트들을 찾아주는 서비스들도 등장했으니 그걸 사용해도 되지만, 어렵지 않으니 직접 파이썬으로 구현을 해보자! 해서 한번 만들어봤습니다.
가장 먼저 해야할 일은 비규제 지역의 아파트들을 긁어오는 겁니다. 네이버 부동산으로도 가능하지만, 저는 kbland.kr 를 이용해 구현했습니다. 우선 크롬을 키고, f12를 누르면 오른쪽에 탭이 하나 뜹니다. 이 탭에서 네트워크 탭을 클릭한 이후, 주소로 찾기 > 강원도 버튼을 클릭해봅시다.
그럼 이제 오른쪽에 저런 코드가 뜹니다. 우린 파이썬을 이용해 request를 해야하니, Request URL를 크롬 주소창에 복붙해봅니다. 해당 값에 오른클릭 -> Copy value -> 주소 창에 붙여넣기 하면 쉽게 할 수 있습니다.
강원도에 있는 시군구명, 법정동코드, 위도, 경도 정보를 얻을 수 있습니다. 디코딩된 URL를 보니 아래와 같은 형식임을 알 수 있겠습니다.
url = "https://api.kbland.kr/land-complex/map/siGunGuAreaNameList?시도명=" + "강원도"
그럼 이제 파이썬 request에 해당 url을 이용해 질의해 봅시다.
import requests
import json
import time
import pandas as pd
from urllib import parse
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0",
"Accept-Encoding": "*",
"Connection": "keep-alive"
}
#강원도에서 시, 군 단위 법정동코드 얻기
url_get_city_codes = 'https://api.kbland.kr/land-complex/map/siGunGuAreaNameList?시도명='
temp_province = '강원도'
year = 2023
url_get_city_codes += temp_province
city_codes_response = requests.get(url_get_city_codes, headers = headers)
city_codes_body = city_codes_response.json()['dataBody']['data']
city_codes = []
for c in city_codes_body:
city_codes.append(c['시군구명'])
잘 뽑아왔는지 확인해봅시다.
",".join(city_codes)
output: '강릉시,고성군,동해시,삼척시,속초시,양구군,양양군,영월군,원주시,인제군,정선군,철원군,춘천시,태백시,평창군,홍천군,화천군,횡성군'
고작 법정동명 하나 알아내려고 이런 귀찮은 짓을 해야하냐 싶으실텐데, URL의 형태와 응답 형태, 입력 변수의 값들을 알아야 구현이 가능한 경우가 앞으로도 계속 있습니다. 가령 무실동에 있는 아파트들의 목록을 뽑고 싶으면 해당 동의 법정동코드를 알아내야 하는데, 일일히 법정동 코드를 찾아서 손으로 입력해줄 수는 없으니까요.
그럼 이제 시군구명을 알아냈으니. 시군구내에 있는 동(읍, 면, 리 포함) 정보를 긁어와 봅시다. 다시 크롬 네트워크 탭의 도움을 받아서 형태를 살펴보면 아래와 같습니다. 아래 예제에서는 원주시의 동 정보를 긁어와 보겠습니다.
url_get_dong_list = 'https://api.kbland.kr/land-complex/map/stutDongAreaNameList?시도명=강원도&시군구명='
c = '원주시'
url_get_dong_list += c
dong_list_response = requests.get(url_get_dong_list, headers = headers)
dong_list_body = dong_list_response.json()['dataBody']['data']
그럼 이제 루프문을 이용해 원주시 내에 있는 아파트 정보들을 긁어와 봅시다.
for d in dong_list_body:
url_get_apt_list = 'https://api.kbland.kr/land-complex/complexComm/hscmList?법정동코드='
url_get_apt_list = url_get_apt_list + d['법정동코드']
apt_list_response = requests.get(url_get_apt_list, headers = headers)
if apt_list_response.json()['dataBody']['resultCode'] == 33210:
continue
apt_list_body = apt_list_response.json()['dataBody']['data']
apt_list_body에 닮긴 값을 보면 아래와 같습니다.
for a in apt_list_body:
print(a)
output:
{'단지기본일련번호': 21153, '물건식별자': 'KBM025293', 'wgs84포인트': 'AAAAAAEBAAAAiaAgZ9D8X0C2roflhapCQA==', '단지명': '개운1차한신휴플러스', '법정동코드': '4213010500', '매물종별구분명': '아파트', '매물종별구분': '01', 'wgs84경도': '127.9502199', '재건축여부': '0', 'wgs84위도': '37.3322112'}
{'단지기본일련번호': 8993, '물건식별자': 'KBM010197', 'wgs84포인트': 'AAAAAAEBAAAAgxWnWgv9X0AXg4dp36pCQA==', '단지명': '개운동원흥3차', '법정동코드': '4213010500', '매물종별구분명': '아파트', '매물종별구분': '01', 'wgs84경도': '127.9538180', '재건축여부': '0', 'wgs84위도': '37.3349430'}
{'단지기본일련번호': 8992, '물건식별자': 'KBM010196', 'wgs84포인트': 'AAAAAAEBAAAApHz3fe78X0AiqBq9GqtCQA==', '단지명': '개운현대', '법정동코드': '4213010500', '매물종별구분명': '아파트', '매물종별구분': '01', 'wgs84경도': '127.9520564', '재건축여부': '0', 'wgs84위도': '37.3367535'}
...
원주시 개운동에 속해 있는 아파트 관련 정보들이 들어있습니다. 그럼 이제 공시가격들을 긁어와 보겠습니다.
for a in apt_list_body:
if a['매물종별구분'] == '01':
apt_id = a['단지기본일련번호']
url_apt_info = 'https://api.kbland.kr/land-complex/complex/typInfo?단지기본일련번호=' + str(apt_id)
url_gongsi_price_list = 'https://api.kbland.kr/land-complex/complex/pubLandPriceByDong?단지기본일련번호=' + str(apt_id)
gongsi_price_list = requests.get(url_gongsi_price_list, headers = headers).json()['dataBody']
if gongsi_price_list['resultCode'] == 33210: #kb에 공시가 정보 없음.
continue
url_gongsi_dong_price_list = 'https://api.kbland.kr/land-complex/complex/dongHoList?단지기본일련번호=' + str(apt_id)
매물종별구분의 값이 01이면 아파트를 나타냅니다. a에서 단지기본일련번호를 이용해 각종 정보들을 조회할 수 있는데, 가끔 공시지가가 등록이 되어 있지 않은 아파트들이 있습니다. 이 경우 resultCode가 33210으로 돌아오니 걸러줍니다. 이렇게 얻어낸 url_gongsi_dong_price_list를 한번 살펴보면...
아파트는 평형, 타입, 층별로 공시지가가 다르기 때문에 한 아파트만 긁어와도 굉장히 데이터가 많습니다. 한 눈에 보기 어려우니 pandas dataframe에 담아보겠습니다.
df_dgpl = pd.json_normalize(dong_gongsi_price_list)
df_dgpl
면적일련번호가 타입과 면적을 unique하게 식별해주니 면적일련번호, 공급면적평, 현재공시지가를 출력하게 만들어 보겠습니다.
df_gpl = df_dgpl.groupby('면적일련번호', as_index = False).min()[['면적일련번호','공급면적평','현재공시지가']]
df_gpl
min()을 넣어뒀기 때문에 각 면적 및 타입별로 가장 싼(보통 1층이겠죠?) 공시지가를 출력하게 됩니다. 이 단지에는 공시지가 1억 이하의 아파트가 없네요. 이제 루프문을 이용해 돌려봅시다.
url_get_dong_list = 'https://api.kbland.kr/land-complex/map/stutDongAreaNameList?시도명=강원도&시군구명='
c = '원주시'
url_get_dong_list += c
dong_list_response = requests.get(url_get_dong_list, headers = headers)
dong_list_body = dong_list_response.json()['dataBody']['data']
df_city = pd.DataFrame()
for d in dong_list_body:
url_get_apt_list = 'https://api.kbland.kr/land-complex/complexComm/hscmList?법정동코드='
url_get_apt_list = url_get_apt_list + d['법정동코드']
apt_list_response = requests.get(url_get_apt_list, headers = headers)
if apt_list_response.json()['dataBody']['resultCode'] == 33210:
continue
apt_list_body = apt_list_response.json()['dataBody']['data']
apt_list = []
years = range(2000,year)
print(d['법정동명'] + '------------------------------------------------------------------')
for a in apt_list_body:
if a['매물종별구분'] == '01':
apt_id = a['단지기본일련번호']
apt_name = a['단지명']
url_apt_info = 'https://api.kbland.kr/land-complex/complex/typInfo?단지기본일련번호=' + str(apt_id)
url_gongsi_price_list = 'https://api.kbland.kr/land-complex/complex/pubLandPriceByDong?단지기본일련번호=' + str(apt_id)
gongsi_price_list = requests.get(url_gongsi_price_list, headers = headers).json()['dataBody']
if gongsi_price_list['resultCode'] == 33210:
continue
url_gongsi_dong_price_list = 'https://api.kbland.kr/land-complex/complex/dongHoList?단지기본일련번호=' + str(apt_id)
dong_gongsi_price_list = requests.get(url_gongsi_dong_price_list, headers = headers).json()['dataBody']['data']
df_dgpl = pd.json_normalize(dong_gongsi_price_list)
df_gpl = df_dgpl.groupby('면적일련번호', as_index = False).min()[['면적일련번호','공급면적평','현재공시지가']]
print(apt_name)
display(df_gpl)
각 단지별 공시지가를 볼 수 있습니다. 그런데 투자자 입장에서 공시지가 1억 미만의 아파트를 사려고 하는데, 공시지가만 보지 않겠죠? 현재 이 단지의 전세가율은 얼만지, 투자금은 얼마나 들어가는지 알고 싶을 겁니다. 다음 편에서는 이런 정보들을 조합해 보겠습니다.
'부동산' 카테고리의 다른 글
파이썬을 이용한 투자용 주택 찾기 (2) (0) | 2023.02.05 |
---|