파이썬(Python)/경기도 미분양 아파트 현황 Plotly subplots

[부동산|2|Plotly] 경기도 미분양 아파트 현황 XML parsing

JJ Goh[Certified customs broker] 2020. 7. 21. 07:00

[부동산|2|Plotly] 경기도 미분양 아파트 현황  XML parsing



 

 Data mining - 선택 데이터의 XML 구조 이해



 이제 Data Sourcing이 되었으니, mining을 곧바로 진행하겠습니다.


 이전에 사용하였던 xml parser함수를 그대로 이용하여 조금 수정해 사용하겠습니다.


 url을 구성하는 방식은 동일하기에 이 자료의 xml구조를 먼저 보고, 어떻게 parsing구문을 구성할지만 보겠습니다.


 이 Data의 샘플URL 결과는 아래와 같습니다.


 <?xml version="1.0" encoding="UTF-8"?>

 <CopertnhousngUnsol>
  <head>
    <list_total_count>431</list_total_count>
    <RESULT>
      <CODE>INFO-000</CODE>
      <MESSAGE>정상 처리되었습니다.</MESSAGE>
    </RESULT>
    <api_version>1.0v</api_version>
  </head>
  <row>
    <SIGUN_NM>김포시</SIGUN_NM>
    <SIGUN_CD>41570</SIGUN_CD>
    <JURISD_AM_GUN_AM_GUN_NM/>
    <JURISD_EMD_NM>마산동</JURISD_EMD_NM>
    <CNSTRCT_LOCPLC_ADDR>경기도 김포시 마산동 김포한강지구 Ac-06BL</CNSTRCT_LOCPLC_ADDR>
    <CNSTRCT_BIZNES_INFO>㈜동일스위트 ㈜동일</CNSTRCT_BIZNES_INFO>
    <IMPLMTN_BIZNES_INFO>㈜동일스위트</IMPLMTN_BIZNES_INFO>
    <PRVATE_PUBL_DIV_NM>민간</PRVATE_PUBL_DIV_NM>
    <RENT_LOTOUT_DIV_NM>분양</RENT_LOTOUT_DIV_NM>
    <SCALE_ACCTO_AR>84.95</SCALE_ACCTO_AR>
    <TOT_LOTOUT_HSHLD_CNT>743</TOT_LOTOUT_HSHLD_CNT>
    <LOTOUT_SUBSCRPT_DE>2018-03</LOTOUT_SUBSCRPT_DE>
    <MOVEIN_PREARNGE_DE>2020-12</MOVEIN_PREARNGE_DE>
    <COMPLTN_YN_DIV_NM>미준공</COMPLTN_YN_DIV_NM>
    <RM/>
    <MT_HSHLD_CNT>0</MT_HSHLD_CNT>
  </row>
  <row>
    <SIGUN_NM>김포시</SIGUN_NM>
    <SIGUN_CD>41570</SIGUN_CD>
    <JURISD_AM_GUN_AM_GUN_NM/>
    <JURISD_EMD_NM>마산동</JURISD_EMD_NM>
    <CNSTRCT_LOCPLC_ADDR>경기도 김포시 마산동 김포한강지구 Ac-06BL</CNSTRCT_LOCPLC_ADDR>
    <CNSTRCT_BIZNES_INFO>㈜동일스위트 ㈜동일</CNSTRCT_BIZNES_INFO>
    <IMPLMTN_BIZNES_INFO>㈜동일스위트</IMPLMTN_BIZNES_INFO>
    <PRVATE_PUBL_DIV_NM>민간</PRVATE_PUBL_DIV_NM>
    <RENT_LOTOUT_DIV_NM>분양</RENT_LOTOUT_DIV_NM>
    <SCALE_ACCTO_AR>84.89</SCALE_ACCTO_AR>
    <TOT_LOTOUT_HSHLD_CNT>139</TOT_LOTOUT_HSHLD_CNT>
    <LOTOUT_SUBSCRPT_DE>2018-03</LOTOUT_SUBSCRPT_DE>
    <MOVEIN_PREARNGE_DE>2020-12</MOVEIN_PREARNGE_DE>
    <COMPLTN_YN_DIV_NM>미준공</COMPLTN_YN_DIV_NM>
    <RM/>
    <MT_HSHLD_CNT>3</MT_HSHLD_CNT>
  </row>
  <row>
    <SIGUN_NM>김포시</SIGUN_NM>
    <SIGUN_CD>41570</SIGUN_CD>
    <JURISD_AM_GUN_AM_GUN_NM/>
    <JURISD_EMD_NM>마산동</JURISD_EMD_NM>
    <CNSTRCT_LOCPLC_ADDR>경기도 김포시 마산동 김포한강지구 Ac-06BL</CNSTRCT_LOCPLC_ADDR>
    <CNSTRCT_BIZNES_INFO>㈜동일스위트 ㈜동일</CNSTRCT_BIZNES_INFO>
    <IMPLMTN_BIZNES_INFO>㈜동일스위트</IMPLMTN_BIZNES_INFO>
    <PRVATE_PUBL_DIV_NM>민간</PRVATE_PUBL_DIV_NM>
    <RENT_LOTOUT_DIV_NM>분양</RENT_LOTOUT_DIV_NM>
    <SCALE_ACCTO_AR>84.99</SCALE_ACCTO_AR>
    <TOT_LOTOUT_HSHLD_CNT>139</TOT_LOTOUT_HSHLD_CNT>
    <LOTOUT_SUBSCRPT_DE>2018-03</LOTOUT_SUBSCRPT_DE>
    <MOVEIN_PREARNGE_DE>2020-12</MOVEIN_PREARNGE_DE>
    <COMPLTN_YN_DIV_NM>미준공</COMPLTN_YN_DIV_NM>
    <RM/>
    <MT_HSHLD_CNT>2</MT_HSHLD_CNT>
  </row>
  <row>
    <SIGUN_NM>김포시</SIGUN_NM>
    <SIGUN_CD>41570</SIGUN_CD>
    <JURISD_AM_GUN_AM_GUN_NM/>
    <JURISD_EMD_NM>마산동</JURISD_EMD_NM>
    <CNSTRCT_LOCPLC_ADDR>경기도 김포시 마산동 김포한강지구 Ac-07bBL</CNSTRCT_LOCPLC_ADDR>
    <CNSTRCT_BIZNES_INFO>㈜동일</CNSTRCT_BIZNES_INFO>
    <IMPLMTN_BIZNES_INFO>㈜동일</IMPLMTN_BIZNES_INFO>
    <PRVATE_PUBL_DIV_NM>민간</PRVATE_PUBL_DIV_NM>
    <RENT_LOTOUT_DIV_NM>분양</RENT_LOTOUT_DIV_NM>
    <SCALE_ACCTO_AR>84.95</SCALE_ACCTO_AR>
    <TOT_LOTOUT_HSHLD_CNT>377</TOT_LOTOUT_HSHLD_CNT>
    <LOTOUT_SUBSCRPT_DE>2018-03</LOTOUT_SUBSCRPT_DE>
    <MOVEIN_PREARNGE_DE>2020-12</MOVEIN_PREARNGE_DE>
    <COMPLTN_YN_DIV_NM>미준공</COMPLTN_YN_DIV_NM>
    <RM/>
    <MT_HSHLD_CNT>1</MT_HSHLD_CNT>
  </row>
  <row>
    <SIGUN_NM>김포시</SIGUN_NM>
    <SIGUN_CD>41570</SIGUN_CD>
    <JURISD_AM_GUN_AM_GUN_NM/>
    <JURISD_EMD_NM>마산동</JURISD_EMD_NM>
    <CNSTRCT_LOCPLC_ADDR>경기도 김포시 마산동 김포한강지구 Ac-07bBL</CNSTRCT_LOCPLC_ADDR>
    <CNSTRCT_BIZNES_INFO>㈜동일</CNSTRCT_BIZNES_INFO>
    <IMPLMTN_BIZNES_INFO>㈜동일</IMPLMTN_BIZNES_INFO>
    <PRVATE_PUBL_DIV_NM>민간</PRVATE_PUBL_DIV_NM>
    <RENT_LOTOUT_DIV_NM>분양</RENT_LOTOUT_DIV_NM>
    <SCALE_ACCTO_AR>84.89</SCALE_ACCTO_AR>
    <TOT_LOTOUT_HSHLD_CNT>165</TOT_LOTOUT_HSHLD_CNT>
    <LOTOUT_SUBSCRPT_DE>2018-03</LOTOUT_SUBSCRPT_DE>
    <MOVEIN_PREARNGE_DE>2020-12</MOVEIN_PREARNGE_DE>
    <COMPLTN_YN_DIV_NM>미준공</COMPLTN_YN_DIV_NM>
    <RM/>
    <MT_HSHLD_CNT>0</MT_HSHLD_CNT>
  </row>
</CopertnhousngUnsol>


 구조를 보시면 row tag 아래에 항목tag가 곧바로 나옵니다. 

 따라서, row안의 값을 모두 불러 들인 후, 각 항목tag별로 find().text를 사용하여 자료를 긁어 들이겠습니다.


 그런데, 여기서 한가지 유의 사항이 있습니다.

 샘플 URL결과에서 태그명이 전부 대문자로 표현되어 있는데요. 실제 XML 결과자료를 열어보면 태그명은 전부 소문자로 구현되어 있습니다. 따라서, find().text를 하실 때, 태그명은 반드시 소문자로 입력하셔야 한다는 점만 착오 없으시면 되겠습니다. 


 경기데이터드림 측에서 이 부분은 수정을 반영해 주는 것이 좋을 것 같습니다.



 Data mining - XML parsing구문 엮기


 그럼 parsing구문을 보시겠습니다.


soup = BeautifulSoup(response.content, 'html.parser')

contents = soup.find_all('row')

rows = []

for x in contents:
SIGUN_NM = x.find("sigun_nm").text
JURISD_AM_GUN_AM_GUN_NM = x.find("jurisd_am_gun_am_gun_nm").text
JURISD_EMD_NM = x.find("jurisd_emd_nm").text
CNSTRCT_LOCPLC_ADDR = x.find("cnstrct_locplc_addr").text
CNSTRCT_BIZNES_INFO = x.find("cnstrct_biznes_info").text

IMPLMTN_BIZNES_INFO = x.find("implmtn_biznes_info").text
PRVATE_PUBL_DIV_NM = x.find("prvate_publ_div_nm").text
MOVEIN_PREARNGE_DE = x.find("movein_prearnge_de").text
SCALE_ACCTO_AR = x.find("scale_accto_ar").text
TOT_LOTOUT_HSHLD_CNT = x.find("tot_lotout_hshld_cnt").text

MT_HSHLD_CNT = x.find("mt_hshld_cnt").text
LOTOUT_SUBSCRPT_DE = x.find("lotout_subscrpt_de").text
RENT_LOTOUT_DIV_NM = x.find("rent_lotout_div_nm").text
COMPLTN_YN_DIV_NM = x.find("compltn_yn_div_nm").text
RM = x.find("rm").text

rows.append({"시군명": SIGUN_NM, "관할군구명": JURISD_AM_GUN_AM_GUN_NM, "관할읍면동명": JURISD_EMD_NM,
"시공소재지위치": CNSTRCT_LOCPLC_ADDR,"시공사정보": CNSTRCT_BIZNES_INFO,
"시행사정보":IMPLMTN_BIZNES_INFO, "민간공공구분" : PRVATE_PUBL_DIV_NM,
"임대분양구분":RENT_LOTOUT_DIV_NM, "면적" : SCALE_ACCTO_AR,
"총분양가구수" : TOT_LOTOUT_HSHLD_CNT, "당월미분양가구수" : MT_HSHLD_CNT,
"분양청약일자" : LOTOUT_SUBSCRPT_DE, "입주예정일자" : MOVEIN_PREARNGE_DE,
"준공여부" : COMPLTN_YN_DIV_NM, "비고" : RM})


 반복문을 통해 rows 라는 빈 리스트에 리스트 묶음을 밀어 넣는 과정이 진행됩니다.


 그리고 생성된 rows는 아래와 같이 DataFrame으로 변환하게 됩니다.


df = pd.DataFrame(rows, columns=["시군명", "관할군구명", "관할읍면동명", "시공소재지위치","시공사정보",
"시행사정보", "민간공공구분", "임대분양구분", "면적", "총분양가구수", "당월미분양가구수",
"분양청약일자", "입주예정일자", "준공여부", "비고"])


 최초 parsing을 할 때, XML로 부터 값을 추출하면서 find().text를 사용함에 따라, 해당 값은 String자료형으로 추출됩니다.

면적과 같은 자료는 실수자료형 또는 정수자료형으로 표현하는 것이 시각화 때 사용하기 편리하기 때문에, 미리 astype(float) 또는 astpye(int)를 활용해 실수자료형 또는 정수자료형으로 변환합니다.



 이제 파이참 터미널로 최종 생성한 df를 출력해 보겠습니다.

 


 pandas DataFrame이 정상적으로 생성된 것이 확인됩니다.


 이제 DataFrame이 갖추어 졌으니, 다음 포스팅에서 plotly 시각화 과정으로 진행해 보겠습니다. 

반응형