파이썬 부동산 매매가 조회 프로그램 만들기 3편 (서울아파트 컬럼 정리) ㅣ 저번 포스트에서는 지역 구분별 코드를 컨버팅해주는 클래스를 만들어보았습니다. 이번 포스트에서는 일단 라이브러리를 이용해서 추출을 한다음에 어떤 컬럼이 필요한지, 필요없는지, 추가해야할 데이터는 무엇이 있을지 생각해보고 추가해서 정제한다음, 대표적으로 서울 아파트 매매가를 조회해보겠습니다.
파이썬 부동산 매매가 조회 프로그램 만들기 3편 (서울아파트 컬럼 정리)
해당 포스팅은 1편, 2편에 이은 3편이므로 1,2편을 보지 않으신 분들은 먼저 포스팅을 보고 오세요!
파이썬 부동산 매매가 조회 프로그램 만들기 2편 (지역코드)
라이브러리 이용해서 한 번 추출해보기
일단 라이브러리를 이용해서 결과물이 어떻게 나오는지 한 번 보겠습니다. 저번 포스트에서 말씀드린 것 처럼, 저는 구글 코랩을 이용하고 있습니다.
https://github.com/WooilJeong/PublicDataReader
제가 원하는건 특정 월의 매매데이터라서, read_data() 메소드를 이용해보겠습니다. 파라미터로는 매물의 종류, 거래유형, 시군구코드, 거래가 발생한 연도와 달을 넘겨주고 실행해봅니다.
그러면 아래와 같이 결과값이 출력됩니다. 일단 print문으로 에러가 있는 api들에 대해 알려주네요. 에러가 있는 서비스들은 따로 제가 조회신청을 하지 않았기 때문에 에러출력되는 것이 당연합니다.
이름설명데이터 타입샘플 데이터항목구분
property_type | 부동산 유형 (아파트, 오피스텔, 단독다가구, 연립다세대, 토지, 분양입주권, 공장창고등) | String | 아파트 | 필수 |
trade_type | 거래 유형 (매매, 전월세) | String | 매매 | 필수 |
sigungu_code | 시군구의 5자리 지역코드 (서울 서초구: 11650, 경기 성남 분당구: 41135) | String | 11650 | 필수 |
year_month | 조회 년월 (단일 월 조회 시 필수) (2023년 1월: 202301) ※ start_year_month와 end_year_month 모두 입력 시 기간 내 조회가 실행됨 | String | 202301 | 조건부 필수 |
start_year_month | 조회 시작 년월 (기간 내 조회 시 필수) (2022년 1월 202201) | String | 202201 | 조건부 필수 |
end_year_month | 조회 종료 년월 (기간 내 조회 시 필수) (2022년 12월: 202212) | String | 202212 | 조건부 필수 |
verbose | 데이터 조회 진행 상황 메시지 출력 여부 (출력: True, 미출력: False) ※ 기본값: False | Boolean | True | 선택 |
- 지역코드
- 도로명
- 법정동
- 지번
- 아파트
- 건축년도
- 층
- 전용면적
- 년
- 월
- 일
- 거래금액 (만원단위)
- 도로명건물본번호코드
- 도로명건물부번호코드
- 도로명시군구코드
- 도로명일련번호코드
- 도로명지상지하코드
- 도로명코드
- 법정동본번코드
- 법정동부번코드
- 법정동시군구코드
- 법정동지번코드
- 일련번호
- 거래유형
- 중개사소재지
- 해제사유발생일
- 해제여부
전체 컬럼은 위와 같습니다. 꽤 많기도하고… 숫자코드만 있어서 얼핏보면 이게 뭘 의미하는지 모르는 내용들도 많습니다. 그래서 필요한 컬럼들은 제외하고 뺄껀 빼주고, 여기서 추가되어야할 컬럼이 있으면 추가작업을 해주어야합니다.
서울아파트 매매가 조회해보기
일단 처음으로는 서울 모든 구의 아파트 매매가를 조회해보는 것으로 시작하겠습니다.
라이브러리를 이용한 API연결
일단 파일의 제일 윗부분에는 필요한 다른 파일들을 import하고, 컨버터의 객체생성과 함께 API연결을 선언합니다.
import json
import os
import pandas as pd
from google.colab import drive
import PublicDataReader as pdr
from PublicDataReader import TransactionPrice
api = pdr.TransactionPrice(service_key)
class DistrictConverter:
def __init__(self):
self.districts = self.__read_district_file()
def __read_district_file(self):
# Google 드라이브를 마운트합니다.
drive.mount('/content/drive')
# 드라이브 내의 JSON 파일 경로를 설정합니다.
json_file_path = '/content/drive/MyDrive/district.json'
# 파일을 열어서 내용을 읽고 JSON으로 변환합니다.
with open(json_file_path, 'r') as f:
return json.loads(f.read())
def get_si_do_code(self, si_do_name):
for district in self.districts:
if si_do_name == district["si_do_name"]:
return district["si_do_code"]
def get_sigungu(self, si_do_code):
for district in self.districts:
if si_do_code == district["si_do_code"]:
return district["sigungu"]
입력받은 시군구 리스트에 대해서 매매가 조회하는 메소드 만들기
이전 포스트와, 본 포스트 상단에 라이브러리로 넘기는 파라미터에서 보이듯이, 조회는 시군구 코드를 기준으로 조회하는데요 조회하고자하는 시군구가 여러개 일 수 있으므로, 시군구 데이터를 리스트로 받아 반복문을 돌리며 조회하는 메소드를 만듭니다.
이 때, API를 조회한 데이터에는 이것이 어떤 시/도의, 어떤 시군구의 데이터인지는 알 수 없습니다. 표시되는 것은 도로명과 읍면동 단위의 데이터만 한글로 나옵니다. (아마도 시군구코드를 넣어서 조회하는 것으로 보아, 조회할 때 이미 어떤 지역인지를 콕 찝어서 조회한다는 유저시나리오를 바탕으로 설계되어있는 것 같습니다.)
따라서, 우리가 결과물을 받아서 어디 데이터인지를 알기 위해서는 시/도 이름과, 시군구이름도 같이 표기되어야 알기 쉽습니다.
# DistrictConverter 인스턴스 생성
converter = DistrictConverter()
# 서울특별시 시/군/구 코드 리스트 가져오기
si_do_name = "서울특별시"
si_do_code = converter.get_si_do_code(si_do_name)
sigungu_list = converter.get_sigungu(si_do_code)
# 모든 시/군/구 데이터를 수집할 DataFrame 초기화
all_data = pd.DataFrame()
# 각 시/군/구 코드에 대해 데이터를 가져오고 시/군/구 이름 추가
for sigungu in sigungu_list:
sigungu_code = sigungu["sigungu_code"]
sigungu_name = sigungu["sigungu_name"]
print(f"Processing data for {sigungu_name} ({sigungu_code})")
파라미터로 시/도 이름, 시군구 데이터가 담긴 리스트, 매물종류, 거래종류, 거래년월 6자리를 받습니다. 이후 시군구리스트에 대해 반복문을 돌아가며 조회를 시작합니다.
조회한 데이터 data 에 대해, 위에서 말씀드린대로 시도 이름과 시군구 이름이 기재된 컬럼으로 생성해줍니다. sigungu_list 에 데이터 하나하나에는 sigungu_code, sigungu_name, eup_myeon_dong 데이터가 json형태로 들어있습니다. 본 시리즈의 2번째 포스트(지역구분별 코드 먼저 준비하기) 를 확인해주세요.
data[“시군구”] = sigungu[“sigungu_name”]
이렇게 시군구 json객체 하나하나에서 시군구이름을 뽑아 컬럼을 하나 만들어줍니다. 그 후에는 기존에 만들었던 시군구 데이터에, 바로 아래에 추가로 데이터를 이어붙여줍니다.
df = pd.concat([data, df])
이렇게해서 서울의 모든 구의 매매데이터를 하나하나 붙여나갑니다.
이 후에, 아까 위에서 만든 전용면적(평) 계산 메소드를 호출해줍니다.
df = caculate_column_data(df)
그러고 마지막으로 컬럼이름을 재정의해주고, 추출한 매매데이터를 리턴합니다. 저는 개인적으로 년, 월, 일 컬럼이 조금 알기 어렵다고 생각해서 아래와 같이 수정했습니다.
# 부동산 데이터를 가져옴
df = api.get_data(
property_type="아파트",
trade_type="매매",
sigungu_code=sigungu_code,
year_month="202402",
)
본 메소드의 전체 코드는 아래와 같습니다.
def get_data_using_sigungu_list(si_do_name, sigungu_list: list, product, transaction, year_month):
df = pd.DataFrame()
for sigungu in sigungu_list:
data = get_data_from_portal(product, transaction, sigungu["sigungu_code"], year_month)
data["시도"] = si_do_name
data["시군구"] = sigungu["sigungu_name"]
df = pd.concat([data, df])
df = caculate_column_data(df)
df.rename(columns={"년": "거래년도",
"월": "거래월",
"일": "거래일"
},
inplace=True)
return df
서울 데이터만 조회하는 메소드 만들기
입력받은 시군구 리스트를 대상으로 매매데이터를 조회하여 리턴하는 메소드가 완성되었습니다. 그럼 이제 어느 시/도의 시군구를 파라미터로 넘겨줘야하냐, 이게 남았습니다.
저는 이번 시리즈 예시에서 일단 서울 데이터만 조회하는 메소드를 만들고 있어서, 서울 시도코드만 따로 추출하는 메소드를 만들어봅니다.
# 시/군/구 이름 및 시/도 이름을 새로운 컬럼으로 추가
df["sigungu_name"] = sigungu_name
df["si_do_name"] = si_do_name # 서울특별시 추가
# 가져온 데이터를 all_data에 추가
all_data = pd.concat([all_data, df], ignore_index=True)
여기에, 마지막으로 인덱스를 리셋해주고, 컬럼들을 제가 원하는 컬럼만으로 간추립니다.
# 필요한 열만 선택하여 데이터 간추리기
columns_to_select = {
"si_do_name": "시도", # 시도
"sigungu_name": "시군구", # 시군구
"umdNm": "법정동", # 법정동
"roadNm": "도로명", # 도로명
"bonbun": "지번", # 지번 (본번)
"aptNm": "아파트", # 아파트
"buildYear": "건축년도", # 건축년도
"excluUseAr": "전용면적", # 전용면적
"floor": "층", # 거래층
"dealYear": "거래년도", # 거래년도
"dealMonth": "거래월", # 거래월
"dealDay": "거래일", # 거래일
"dealAmount": "거래금액", # 거래금액
"aptSeq": "일련번호", # 일련번호
"dealingGbn": "거래유형", # 거래유형
"estateAgentSggNm": "중개사소재지", # 중개사소재지
"cdealType": "해제여부", # 해제여부
"cdealDay": "해제사유발생일" # 해제사유발생일
}
제가 원하는 컬럼목록은 아래와 같습니다.
"시도",
"시군구",
"법정동",
"도로명",
"지번",
"아파트",
"건축년도",
"전용면적",
"전용면적(평)",
"거래년도",
"거래월",
"거래일",
"거래금액",
"일련번호",
"거래유형",
"중개사소재지",
"해제여부",
"해제사유발생일"
]
이렇게해서 내용이 일단 완료되었습니다. 전체 코드는 아래와 같습니다.
import json
import os
import pandas as pd
from google.colab import drive
import PublicDataReader as pdr
from PublicDataReader import TransactionPrice
api = pdr.TransactionPrice(service_key)
class DistrictConverter:
def __init__(self):
self.districts = self.__read_district_file()
def __read_district_file(self):
# Google 드라이브를 마운트합니다.
drive.mount('/content/drive')
# 드라이브 내의 JSON 파일 경로를 설정합니다.
json_file_path = '/content/drive/MyDrive/district.json'
# 파일을 열어서 내용을 읽고 JSON으로 변환합니다.
with open(json_file_path, 'r') as f:
return json.loads(f.read())
def get_si_do_code(self, si_do_name):
for district in self.districts:
if si_do_name == district["si_do_name"]:
return district["si_do_code"]
def get_sigungu(self, si_do_code):
for district in self.districts:
if si_do_code == district["si_do_code"]:
return district["sigungu"]
# DistrictConverter 인스턴스 생성
converter = DistrictConverter()
# 서울특별시 시/군/구 코드 리스트 가져오기
si_do_name = "서울특별시"
si_do_code = converter.get_si_do_code(si_do_name)
sigungu_list = converter.get_sigungu(si_do_code)
# 모든 시/군/구 데이터를 수집할 DataFrame 초기화
all_data = pd.DataFrame()
# 각 시/군/구 코드에 대해 데이터를 가져오고 시/군/구 이름 추가
for sigungu in sigungu_list:
sigungu_code = sigungu["sigungu_code"]
sigungu_name = sigungu["sigungu_name"]
print(f"Processing data for {sigungu_name} ({sigungu_code})")
# 부동산 데이터를 가져옴
df = api.get_data(
property_type="아파트",
trade_type="매매",
sigungu_code=sigungu_code,
year_month="202402",
)
# 시/군/구 이름 및 시/도 이름을 새로운 컬럼으로 추가
df["sigungu_name"] = sigungu_name
df["si_do_name"] = si_do_name # 서울특별시 추가
# 가져온 데이터를 all_data에 추가
all_data = pd.concat([all_data, df], ignore_index=True)
# 필요한 열만 선택하여 데이터 간추리기
# 필요한 열만 선택하여 데이터 간추리기
columns_to_select = {
"si_do_name": "시도", # 시도
"sigungu_name": "시군구", # 시군구
"umdNm": "법정동", # 법정동
"roadNm": "도로명", # 도로명
"bonbun": "지번", # 지번 (본번)
"aptNm": "아파트", # 아파트
"buildYear": "건축년도", # 건축년도
"excluUseAr": "전용면적", # 전용면적
"floor": "층", # 거래층
"dealYear": "거래년도", # 거래년도
"dealMonth": "거래월", # 거래월
"dealDay": "거래일", # 거래일
"dealAmount": "거래금액", # 거래금액
"aptSeq": "일련번호", # 일련번호
"dealingGbn": "거래유형", # 거래유형
"estateAgentSggNm": "중개사소재지", # 중개사소재지
"cdealType": "해제여부", # 해제여부
"cdealDay": "해제사유발생일" # 해제사유발생일
}
# 필요한 열만 선택하여 데이터프레임을 새로 생성하고, 열 이름을 한글로 변경
selected_data = all_data[list(columns_to_select.keys())].rename(columns=columns_to_select)
# 파일명을 규칙적으로 지정: 서울특별시_202401_매매.csv
file_name = f'{si_do_name}_202401_매매.csv'.replace(" ", "") # 파일명에서 공백 제거
# 필요한 열만 남긴 데이터를 CSV 파일로 저장
csv_path = f'/content/drive/MyDrive/{file_name}'
selected_data.to_csv(csv_path, index=False)
# 파일 저장 후, 선택된 데이터의 일부를 출력하여 확인
print(selected_data.head())
코랩에서 데이터 활용 이용해서 매매가 구해보기
이제, 코랩에서 해당 데이터를 실행해봅니다.
그러면 아래와 같이 제가 원하는 데이터만 보기좋게 딱 나옵니다.
데이터가 700가 훌쩍 넘는 것을 보니, 서울의 모든 구의 아파트 매매데이터가 다 나온 것 같네요.
이렇게 서울 아파트 매매 데이터를 구해보았습니다. 위에 파라미터를 아파트 로 넣었는데, 연립/다세대 매매 데이터 API에 대한 신청도 해놓으셨다면, 파라미터로 연립/다세대 를 넣으셔서 이른바 빌라 매매 데이터도 구해볼 수 있습니다.
다음 포스트에서는 서울 이외의 시도, 시군구에 대한 매매데이터를 구하는 메소드를 만들어봅니다.