공공데이터포털의 특징은 자료를 활용을 요약하자면

1. 회원 가입 후 '사용자 인증키'를 생성해야한다.
2. 이후 원하는 데이터를 '활용 신청'을 해서 승인이 떨어지고 활용 권한을 획득해야한다. (실제 활용 가능 시간까지 약 1일 정도 소요) (파일데이터는 활용 신청 없이 그냥 다운로드 하여 사용 가능)
3. 제공되는 데이터는 파일데이터, JSON, XML 등이 있다.

 

1. XML이란?

eXtensible Markup Language로 태그를 이용해 데이터 구조를 기술하는 마크업 언어의 한 종류다. (한 마디로 HTML의 사촌)

따라서 requests.get으로 response를 받아온 뒤, BeautifulSoup로 xml로 바꿔 예쁘게 담아준 다음, HTML 태그 뽑아낼 때 사용했던 방식을 그대로 적용하면 된다. (find, find_all)

이 때 필요한 변수의 정보는 공공데이터포털에서 확인할 수 있다.

 

우선 아래로 내려보자.

이런식으로 어떤 데이터에는 어떤 키를 사용해야하는지, 그 키는 필수인지, 옵션인지를 알려준다.
(항목의 크기와 그 데이터의 샘플이 어떤지까지 보여준다.)

 

그리고 다시 위로 가보자. 자세한 정보는 반드시 '참고문서'를 다운 받아서 열어보도록 한다.

법정도 코드는 '행정표준코드관리시스템'에서 확인할 수 있다.

www.code.go.kr/stdcode/regCodeL.do

 

법정동코드목록조회 - 행정표준코드관리시스템

 

www.code.go.kr

 

 

2. 파이썬으로 데이터 불러오기

활용 신청한 데이터를 '상세 보기'를 눌러 들어가면 '서비스URL'이라고 있다. 이것이 해당 XML로 구성된 데이터 전체의 기본 URL이다.

 

'상세 보기' 하단에 보면 요청 변수에 대한 예시가 있다. 위 URL에 필수 옵션을 이용해 데이터를 불러와보자.

 

www.openapi.molit.go.kr/OpenAPI_ToolInstallPackage/service/rest/RTMSOBJSvc/getRTMSDataSvcAptTradeDev?ServiceKey=내API키&LAWD_CD=11110&DEAL_YWD=201512

URL에 이걸 그대로 넣어야하는데 너무 기니까 가독성을 위해서 기본 URL과 파라미터를 분리시키고, 파이썬으로 합쳐서 URL을 보내보자.

xmlUrl = 'www.openapi.molit.go.kr/OpenAPI_ToolInstallPackage/service/rest/RTMSOBJSvc/getRTMSDataSvcAptTradeDev'

My_API_Key = '내API키'

queryParams = + urlencode({quote_plus(ServiceKey) : MyAPI_Key, quote_plus(LAWD_CD) : '11110', quote_plus(DEAL_YWD) : '201512'})

와 같다.

 

import requests, bs4
import pandas as pd
from lxml import html
from urllib.request import Request, urlopen
from urllib.parse import urlencode, quote_plus, unquote

# 1. URL 파라미터 분리하기.
# Service URL
xmlUrl = 'http://openapi.molit.go.kr/OpenAPI_ToolInstallPackage/service/rest/RTMSOBJSvc/getRTMSDataSvcAptTradeDev'

My_API_Key = unquote('sjOpJdbWHR3lhq4f8w5Dg6lc6IDZPdXeue%2BzGqY47h4Jp4sKy8SE5wKtpoHT7yfpI1NMFLyMMYHSiY4MNP6dhQ%3D%3D')    # 아래 내가 받은 인증키가 안 되서 수업용 인증키 사용.
# My_API_Key = unquote('Agq7hySmyMi1FFU9kYibP%2BEnxYepQ%2FB6Dn%2Bw9lsYKVSCDjTwIdvpjmuhJrtyQrhipg3F3a4jbSq%2FLxHi%2FdUIoQ%3D%3D')    # 사용자 인증키
queryParams = '?' + urlencode(    # get 방식으로 쿼리를 분리하기 위해 '?'를 넣은 것이다. 메타코드 아님.
    {
        quote_plus('ServiceKey') : My_API_Key,    # 필수 항목 1 : 서비스키 (본인의 서비스키)
        quote_plus('LAWD_CD') : '11110',          # 필수 항목 2 : 지역코드 (법정코드목록조회에서 확인)
        quote_plus('DEAL_YMD') : '201512'         # 픽수 항목 3 : 계약월
     }
)

response = requests.get(xmlUrl + queryParams).text.encode('utf-8')
xmlobj = bs4.BeautifulSoup(response, 'lxml-xml')
# xmlobj    # 디버깅용.


결과 : 

<?xml version="1.0" encoding="utf-8"?>
<response><header><resultCode>00</resultCode><resultMsg>NORMAL SERVICE.</resultMsg></header><body><items><item><거래금액>    82,500</거래금액><건축년도>2008</건축년도><년>2015</년><도로명>사직로8길</도로명><도로명건물본번호코드>00004</도로명건물본번호코드><도로명건물부번호코드>00000</도로명건물부번호코드><도로명시군구코드>11110</도로명시군구코드><도로명일련번호코드>03</도로명일련번호코드><도로명지상지하코드>0</도로명지상지하코드><도로명코드>4100135</도로명코드><법정동> 사직동</법정동><법정동본번코드>0009</법정동본번코드><법정동부번코드>0000</법정동부번코드><법정동시군구코드>11110</법정동시군구코드><법정동읍면동코드>11500</법정동읍면동코드><법정동지번코드>1</법정동지번코드><아파트>광화문풍림스페이스본(101동~105동)</아파트><월>12</월><일>10</일><일련번호>11110-2203</일련번호><전용면적>94.51</전용면적><지번>9</지번><지역코드>11110</지역코드><층>11</층></item><item><거래금액>    60,000</거래금액><건축년도>1981</건축년도><년>2015</년><도로명>세종대로23길</도로명><도로명건물본번호코드>00047</도로명건물본번호코드><도로명건물부번호코드>00000</도로명건물부번호코드><도로명시군구코드>11110</도로명시군구코드><도로명일련번호코드>02</도로명일련번호코드><도로명지상지하코드>0</도로명지상지하코드><도로명코드>4100190</도로명코드><법정동> 당주동</법정동><법정동본번코드>0145</법정동본번코드><법정동부번코드>0000</법정동부번코드><법정동시군구코드>11110</법정동시군구코드><법정동읍면동코드>11700</법정동읍면동코드><법정동지번코드>1</법정동지번코드><아파트>롯데미도파광화문빌딩</아파트><월>12</월><일>22</일><일련번호>11110-12</일련번호><전용면적>149.95</전용면적><지번>145</지번><지역코드>11110</지역코드><층>8</층></item><item><거래금액>   130,000</거래금액><건축년도>2004</건축년도><년>2015</년><도로명>경희궁2길</도로명><도로명건물본번호코드>00005</도로명건물본번호코드><도로명건물부번호코드>00005</도로명건물부번호코드><도로명시군구코드>11110</도로명시군구코드><도로명일련번호코드>01</도로명일련번호코드><도로명지상지하코드>0</도로명지상지하코드><도로명코드>4100005</도로명코드><법정동> 내수동</법정동><법정동본번코드>0110</법정동본번코드><법정동부번코드>0015</법정동부번코드><법정동시군구코드>11110</법정동시군구코드><법정동읍면동코드>11800</법정동읍면동코드><법정동지번코드>1</법정동지번코드><아파트>킹스매너</아파트><월>12</월><일>8</일><일련번호>11110-118</일련번호><전용면적>194.43</전용면적><지번>110-15</지번><지역코드>11110</지역코드><층>6</층></item><item><거래금액>   105,000</거래금액><건축년도>2004</건축년도><년>2015</년><도로명>사직로8길</도로명><도로명건물본번호코드>00024</도로명건물본번호코드><도로명건물부번호코드>00000</도로명건물부번호코드><도로명시군구코드>11110</도로명시군구코드><도로명일련번호코드>05</도로명일련번호코드><도로명지상지하코드>0</도로명지상지하코드><도로명코드>4100135</도로명코드><법정동> 내수동</법정동><법정동본번코드>0071</법정동본번코드><법정동부번코드>0000</법정동부번코드><법정동시군구코드>11110</법정동시군구코드><법정동읍면동코드>11800</법정동읍면동코드><법정동지번코드>1</법정동지번코드><아파트>경희궁의아침2단지</아파트><월>12</월><일>14</일><일련번호>11110-115</일련번호><전용면적>124.17</전용면적><지번>71</지번><지역코드>11110</지역코드><층>8</층></item><item><거래금액>   120,000</거래금액><건축년도>2003</건축년도><년>2015</년><도로명>사직로8길</도로명><도로명건물본번호코드>00020</도로명건물본번호코드><도로명건물부번호코드>00000</도로명건물부번호코드><도로명시군구코드>11110</도로명시군구코드><도로명일련번호코드>05</도로명일련번호코드><도로명지상지하코드>0</도로명지상지하코드><도로명코드>4100135</도로명코드><법정동> 내수동</법정동><법정동본번코드>0095</법정동본번코드><법정동부번코드>0000</법정동부번코드><법정동시군구코드>11110</법정동시군구코드><법정동읍면동코드>11800</법정동읍면동코드><법정동지번코드>1</법정동지번코드><아파트>경희궁 파크팰리스</아파트><월>12</월><일>24</일><일련번호>11110-107</일련번호><전용면적>146.33</전용면적><지번>95</지번><지역코드>11110</지역코드><층>4</층></item><item><거래금액>    17,000</거래금액><건축년도>2014</건축년도><년>2015</년><도로명>대학로</도로명><도로명건물본번호코드>00047</도로명건물본번호코드><도로명건물부번호코드>00000</도로명건물부번호코드><도로명시군구코드>11110</도로명시군구코드><도로명일련번호코드>05</도로명일련번호코드><도로명지상지하코드>0</도로명지상지하코드><도로명코드>3100002</도로명코드><법정동> 연건동</법정동><법정동본번코드>0195</법정동본번코드><법정동부번코드>0010</법정동부번코드><법정동시군구코드>11110</법정동시군구코드><법정동읍면동코드>16600</법정동읍면동코드><법정동지번코드>1</법정동지번코드><아파트>이화에수풀</아파트><월>12</월><일>17</일><일련번호>11110-2359</일련번호><전용면적>16.98</전용면적><지번>195-10</지번><지역코드>11110</지역코드><층>8</층></item><item><거래금액>    17,000</거래금액><건축년도>2014</건축년도><년>2015</년><도로명>대학로</도로명><도로명건물본번호코드>00047</도로명건물본번호코드><도로명건물부번호코드>00000</도로명건물부번호코드><도로명시군구코드>11110</도로명시군구코드><도로명일련번호코드>05</도로명일련번호코드><도로명지상지하코드>0</도로명지상지하코드><도로명코드>3100002</도로명코드><법정동> 연건동</법정동><법정동본번코드>0195</법정동본번코드><법정동부번코드>0010</법정동부번코드><법정동시군구코드>11110</법정동시군구코드><법정동읍면동코드>16600</법정동읍면동코드><법정동지번코드>1</법정동지번코드><아파트>이화에수풀</아파트><월>12</월><일>18</일><일련번호>11110-2359</일련번호><전용면적>16.98</전용면적><지번>195-10</지번><지역코드>11110</지역코드><층>4</층></item><item><거래금액>    57,000</거래금액><건축년도>2006</건축년도><년>2015</년><도로명>혜화로3가길</도로명><도로명건물본번호코드>00030</도로명건물본번호코드><도로명건물부번호코드>00000</도로명건물부번호코드><도로명시군구코드>11110</도로명시군구코드><도로명일련번호코드>01</도로명일련번호코드><도로명지상지하코드>0</도로명지상지하코드><도로명코드>4100544</도로명코드><법정동> 명륜1가</법정동><법정동본번코드>0019</법정동본번코드><법정동부번코드>0000</법정동부번코드><법정동시군구코드>11110</법정동시군구코드><법정동읍면동코드>17000</법정동읍면동코드><법정동지번코드>1</법정동지번코드><아파트>렉스빌</아파트><월>12</월><일>29</일><일련번호>11110-973</일련번호><전용면적>106.98</전용면적><지번>19</지번><지역코드>11110</지역코드><층>3</층></item><item><거래금액>    44,000</거래금액><건축년도>1995</건축년도><년>2015</년><도로명>창경궁로</도로명><도로명건물본번호코드>00265</도로명건물본번호코드><도로명건물부번호코드>00000</도로명건물부번호코드><도로명시군구코드>11110</도로명시군구코드><도로명일련번호코드>07</도로명일련번호코드><도로명지상지하코드>0</도로명지상지하코드><도로명코드>3005008</도로명코드><법정동> 명륜2가</법정동><법정동본번코드>0004</법정동본번코드><법정동부번코드>0000</법정동부번코드><법정동시군구코드>11110</법정동시군구코드><법정동읍면동코드>17100</법정동읍면동코드><법정동지번코드>1</법정동지번코드><아파트>아남1</아파트><월>12</월><일>1</일><일련번호>11110-25</일련번호><전용면적>84.8</전용면적><지번>4</지번><지역코드>11110</지역코드><층>18</층></item><item><거래금액>    52,000</거래금액><건축년도>1995</건축년도><년>2015</년><도로명>창경궁로</도로명><도로명건물본번호코드>00265</도로명건물본번호코드><도로명건물부번호코드>00000</도로명건물부번호코드><도로명시군구코드>11110</도로명시군구코드><도로명일련번호코드>07</도로명일련번호코드><도로명지상지하코드>0</도로명지상지하코드><도로명코드>3005008</도로명코드><법정동> 명륜2가</법정동><법정동본번코드>0004</법정동본번코드><법정동부번코드>0000</법정동부번코드><법정동시군구코드>11110</법정동시군구코드><법정동읍면동코드>17100</법정동읍면동코드><법정동지번코드>1</법정동지번코드><아파트>아남1</아파트><월>12</월><일>10</일><일련번호>11110-25</일련번호><전용면적>84.9</전용면적><지번>4</지번><지역코드>11110</지역코드><층>12</층></item></items><numOfRows>10</numOfRows><pageNo>1</pageNo><totalCount>49</totalCount></body></response>

 

 

3. 데이터 분리하기

XML 태그는 HTML 태그와 유사하지만 좀 더 간단하다. body 안에는 items 태그가 있고 그 안에는 item태그로 구성되어진다.

 

따라서 item 태그로 분리해보자.

rows = xmlobj.findAll('item')
# rows # 디버깅용.

결과 :


[7]:
[<item><거래금액>    82,500</거래금액><건축년도>2008</건축년도><년>2015</년><도로명>사직로8길</도로명><도로명건물본번호코드>00004</도로명건물본번호코드><도로명건물부번호코드>00000</도로명건물부번호코드><도로명시군구코드>11110</도로명시군구코드><도로명일련번호코드>03</도로명일련번호코드><도로명지상지하코드>0</도로명지상지하코드><도로명코드>4100135</도로명코드><법정동> 사직동</법정동><법정동본번코드>0009</법정동본번코드><법정동부번코드>0000</법정동부번코드><법정동시군구코드>11110</법정동시군구코드><법정동읍면동코드>11500</법정동읍면동코드><법정동지번코드>1</법정동지번코드><아파트>광화문풍림스페이스본(101동~105동)</아파트><월>12</월><일>10</일><일련번호>11110-2203</일련번호><전용면적>94.51</전용면적><지번>9</지번><지역코드>11110</지역코드><층>11</층></item>,
 <item><거래금액>    60,000</거래금액><건축년도>1981</건축년도><년>2015</년><도로명>세종대로23길</도로명><도로명건물본번호코드>00047</도로명건물본번호코드><도로명건물부번호코드>00000</도로명건물부번호코드><도로명시군구코드>11110</도로명시군구코드><도로명일련번호코드>02</도로명일련번호코드><도로명지상지하코드>0</도로명지상지하코드><도로명코드>4100190</도로명코드><법정동> 당주동</법정동><법정동본번코드>0145</법정동본번코드><법정동부번코드>0000</법정동부번코드><법정동시군구코드>11110</법정동시군구코드><법정동읍면동코드>11700</법정동읍면동코드><법정동지번코드>1</법정동지번코드><아파트>롯데미도파광화문빌딩</아파트><월>12</월><일>22</일><일련번호>11110-12</일련번호><전용면적>149.95</전용면적><지번>145</지번><지역코드>11110</지역코드><층>8</층></item>,
 <item><거래금액>   130,000</거래금액><건축년도>2004</건축년도><년>2015</년><도로명>경희궁2길</도로명><도로명건물본번호코드>00005</도로명건물본번호코드><도로명건물부번호코드>00005</도로명건물부번호코드><도로명시군구코드>11110</도로명시군구코드><도로명일련번호코드>01</도로명일련번호코드><도로명지상지하코드>0</도로명지상지하코드><도로명코드>4100005</도로명코드><법정동> 내수동</법정동><법정동본번코드>0110</법정동본번코드><법정동부번코드>0015</법정동부번코드><법정동시군구코드>11110</법정동시군구코드><법정동읍면동코드>11800</법정동읍면동코드><법정동지번코드>1</법정동지번코드><아파트>킹스매너</아파트><월>12</월><일>8</일><일련번호>11110-118</일련번호><전용면적>194.43</전용면적><지번>110-15</지번><지역코드>11110</지역코드><층>6</층></item>,
 <item><거래금액>   105,000</거래금액><건축년도>2004</건축년도><년>2015</년><도로명>사직로8길</도로명><도로명건물본번호코드>00024</도로명건물본번호코드><도로명건물부번호코드>00000</도로명건물부번호코드><도로명시군구코드>11110</도로명시군구코드><도로명일련번호코드>05</도로명일련번호코드><도로명지상지하코드>0</도로명지상지하코드><도로명코드>4100135</도로명코드><법정동> 내수동</법정동><법정동본번코드>0071</법정동본번코드><법정동부번코드>0000</법정동부번코드><법정동시군구코드>11110</법정동시군구코드><법정동읍면동코드>11800</법정동읍면동코드><법정동지번코드>1</법정동지번코드><아파트>경희궁의아침2단지</아파트><월>12</월><일>14</일><일련번호>11110-115</일련번호><전용면적>124.17</전용면적><지번>71</지번><지역코드>11110</지역코드><층>8</층></item>,
 <item><거래금액>   120,000</거래금액><건축년도>2003</건축년도><년>2015</년><도로명>사직로8길</도로명><도로명건물본번호코드>00020</도로명건물본번호코드><도로명건물부번호코드>00000</도로명건물부번호코드><도로명시군구코드>11110</도로명시군구코드><도로명일련번호코드>05</도로명일련번호코드><도로명지상지하코드>0</도로명지상지하코드><도로명코드>4100135</도로명코드><법정동> 내수동</법정동><법정동본번코드>0095</법정동본번코드><법정동부번코드>0000</법정동부번코드><법정동시군구코드>11110</법정동시군구코드><법정동읍면동코드>11800</법정동읍면동코드><법정동지번코드>1</법정동지번코드><아파트>경희궁 파크팰리스</아파트><월>12</월><일>24</일><일련번호>11110-107</일련번호><전용면적>146.33</전용면적><지번>95</지번><지역코드>11110</지역코드><층>4</층></item>,
 <item><거래금액>    17,000</거래금액><건축년도>2014</건축년도><년>2015</년><도로명>대학로</도로명><도로명건물본번호코드>00047</도로명건물본번호코드><도로명건물부번호코드>00000</도로명건물부번호코드><도로명시군구코드>11110</도로명시군구코드><도로명일련번호코드>05</도로명일련번호코드><도로명지상지하코드>0</도로명지상지하코드><도로명코드>3100002</도로명코드><법정동> 연건동</법정동><법정동본번코드>0195</법정동본번코드><법정동부번코드>0010</법정동부번코드><법정동시군구코드>11110</법정동시군구코드><법정동읍면동코드>16600</법정동읍면동코드><법정동지번코드>1</법정동지번코드><아파트>이화에수풀</아파트><월>12</월><일>17</일><일련번호>11110-2359</일련번호><전용면적>16.98</전용면적><지번>195-10</지번><지역코드>11110</지역코드><층>8</층></item>,
 <item><거래금액>    17,000</거래금액><건축년도>2014</건축년도><년>2015</년><도로명>대학로</도로명><도로명건물본번호코드>00047</도로명건물본번호코드><도로명건물부번호코드>00000</도로명건물부번호코드><도로명시군구코드>11110</도로명시군구코드><도로명일련번호코드>05</도로명일련번호코드><도로명지상지하코드>0</도로명지상지하코드><도로명코드>3100002</도로명코드><법정동> 연건동</법정동><법정동본번코드>0195</법정동본번코드><법정동부번코드>0010</법정동부번코드><법정동시군구코드>11110</법정동시군구코드><법정동읍면동코드>16600</법정동읍면동코드><법정동지번코드>1</법정동지번코드><아파트>이화에수풀</아파트><월>12</월><일>18</일><일련번호>11110-2359</일련번호><전용면적>16.98</전용면적><지번>195-10</지번><지역코드>11110</지역코드><층>4</층></item>,
 <item><거래금액>    57,000</거래금액><건축년도>2006</건축년도><년>2015</년><도로명>혜화로3가길</도로명><도로명건물본번호코드>00030</도로명건물본번호코드><도로명건물부번호코드>00000</도로명건물부번호코드><도로명시군구코드>11110</도로명시군구코드><도로명일련번호코드>01</도로명일련번호코드><도로명지상지하코드>0</도로명지상지하코드><도로명코드>4100544</도로명코드><법정동> 명륜1가</법정동><법정동본번코드>0019</법정동본번코드><법정동부번코드>0000</법정동부번코드><법정동시군구코드>11110</법정동시군구코드><법정동읍면동코드>17000</법정동읍면동코드><법정동지번코드>1</법정동지번코드><아파트>렉스빌</아파트><월>12</월><일>29</일><일련번호>11110-973</일련번호><전용면적>106.98</전용면적><지번>19</지번><지역코드>11110</지역코드><층>3</층></item>,
 <item><거래금액>    44,000</거래금액><건축년도>1995</건축년도><년>2015</년><도로명>창경궁로</도로명><도로명건물본번호코드>00265</도로명건물본번호코드><도로명건물부번호코드>00000</도로명건물부번호코드><도로명시군구코드>11110</도로명시군구코드><도로명일련번호코드>07</도로명일련번호코드><도로명지상지하코드>0</도로명지상지하코드><도로명코드>3005008</도로명코드><법정동> 명륜2가</법정동><법정동본번코드>0004</법정동본번코드><법정동부번코드>0000</법정동부번코드><법정동시군구코드>11110</법정동시군구코드><법정동읍면동코드>17100</법정동읍면동코드><법정동지번코드>1</법정동지번코드><아파트>아남1</아파트><월>12</월><일>1</일><일련번호>11110-25</일련번호><전용면적>84.8</전용면적><지번>4</지번><지역코드>11110</지역코드><층>18</층></item>,
 <item><거래금액>    52,000</거래금액><건축년도>1995</건축년도><년>2015</년><도로명>창경궁로</도로명><도로명건물본번호코드>00265</도로명건물본번호코드><도로명건물부번호코드>00000</도로명건물부번호코드><도로명시군구코드>11110</도로명시군구코드><도로명일련번호코드>07</도로명일련번호코드><도로명지상지하코드>0</도로명지상지하코드><도로명코드>3005008</도로명코드><법정동> 명륜2가</법정동><법정동본번코드>0004</법정동본번코드><법정동부번코드>0000</법정동부번코드><법정동시군구코드>11110</법정동시군구코드><법정동읍면동코드>17100</법정동읍면동코드><법정동지번코드>1</법정동지번코드><아파트>아남1</아파트><월>12</월><일>10</일><일련번호>11110-25</일련번호><전용면적>84.9</전용면적><지번>4</지번><지역코드>11110</지역코드><층>12</층></item>]

 

rows[0]을 조회해보자.

rows[0]

결과 :

<item><거래금액>    82,500</거래금액><건축년도>2008</건축년도><년>2015</년><도로명>사직로8길</도로명><도로명건물본번호코드>00004</도로명건물본번호코드><도로명건물부번호코드>00000</도로명건물부번호코드><도로명시군구코드>11110</도로명시군구코드><도로명일련번호코드>03</도로명일련번호코드><도로명지상지하코드>0</도로명지상지하코드><도로명코드>4100135</도로명코드><법정동> 사직동</법정동><법정동본번코드>0009</법정동본번코드><법정동부번코드>0000</법정동부번코드><법정동시군구코드>11110</법정동시군구코드><법정동읍면동코드>11500</법정동읍면동코드><법정동지번코드>1</법정동지번코드><아파트>광화문풍림스페이스본(101동~105동)</아파트><월>12</월><일>10</일><일련번호>11110-2203</일련번호><전용면적>94.51</전용면적><지번>9</지번><지역코드>11110</지역코드><층>11</층></item>

 

0번 행(rows[0])의 모든 값을 하나의 column값으로 보고 리스트에 담아보자.

# 한 개 행의 모든 컬럼값을 리스트에 담아보자.
columns = rows[0].find_all()
columns

결과 :

[<거래금액>    82,500</거래금액>,
 <건축년도>2008</건축년도>,
 <년>2015</년>,
 <도로명>사직로8길</도로명>,
 <도로명건물본번호코드>00004</도로명건물본번호코드>,
 <도로명건물부번호코드>00000</도로명건물부번호코드>,
 <도로명시군구코드>11110</도로명시군구코드>,
 <도로명일련번호코드>03</도로명일련번호코드>,
 <도로명지상지하코드>0</도로명지상지하코드>,
 <도로명코드>4100135</도로명코드>,
 <법정동> 사직동</법정동>,
 <법정동본번코드>0009</법정동본번코드>,
 <법정동부번코드>0000</법정동부번코드>,
 <법정동시군구코드>11110</법정동시군구코드>,
 <법정동읍면동코드>11500</법정동읍면동코드>,
 <법정동지번코드>1</법정동지번코드>,
 <아파트>광화문풍림스페이스본(101동~105동)</아파트>,
 <월>12</월>,
 <일>10</일>,
 <일련번호>11110-2203</일련번호>,
 <전용면적>94.51</전용면적>,
 <지번>9</지번>,
 <지역코드>11110</지역코드>,
 <층>11</층>]
 
 
 # 리스트 조회해보기
 columns[0].name
 
 결과 : '거래금액'
 
 
 columns[0].text
 
 결과 : '    82,500'

 

반복문으로 만들어보자.

rowList = []
nameList = []
columnList = []

columnsLen = len(columns)
for j in range(0, columnsLen):
    eachColumn = columns[j].text
    columnList.append(eachColumn)
rowList.append(columnList)

 

이번에는 전체 데이터 값에 대해 반복문을 만들어보자. (매트릭스 리스트를 만들어보자.)

# 모든 행과 열의 값을 모아 매트릭스로 만들어보자.
rowList = []
nameList = []
columnList = []

rowsLen = len(rows)
for i in range(0, rowsLen):
    columns = rows[i].find_all()
    
    columnsLen = len(columns)
    for j in range(0, columnsLen):
        # 첫 번째 행 데이터 값 수집 시에만 컬럼 값을 저장한다. (어차피 rows[0], rows[1], ... 모두 컬럼헤더는 동일한 값을 가지기 때문에 매번 반복할 필요가 없다.)
        if i == 0:
            nameList.append(columns[j].name)
        # 컬럼값은 모든 행의 값을 저장해야한다.    
        eachColumn = columns[j].text
        columnList.append(eachColumn)
    rowList.append(columnList)
    columnList = []    # 다음 row의 값을 넣기 위해 비워준다. (매우 중요!!)
    
result = pd.DataFrame(rowList, columns=nameList)
result.head()

 

 

 

완성본

import requests, bs4
import pandas as pd
from lxml import html
from urllib.request import Request, urlopen
from urllib.parse import urlencode, quote_plus, unquote

# 1. URL 파라미터 분리하기.
# Service URL
xmlUrl = 'http://openapi.molit.go.kr/OpenAPI_ToolInstallPackage/service/rest/RTMSOBJSvc/getRTMSDataSvcAptTradeDev'

My_API_Key = unquote('sjOpJdbWHR3lhq4f8w5Dg6lc6IDZPdXeue%2BzGqY47h4Jp4sKy8SE5wKtpoHT7yfpI1NMFLyMMYHSiY4MNP6dhQ%3D%3D')
# My_API_Key = unquote('Agq7hySmyMi1FFU9kYibP%2BEnxYepQ%2FB6Dn%2Bw9lsYKVSCDjTwIdvpjmuhJrtyQrhipg3F3a4jbSq%2FLxHi%2FdUIoQ%3D%3D')    # 사용자 인증키
queryParams = '?' + urlencode(    # get 방식으로 쿼리를 분리하기 위해 '?'를 넣은 것이다. 메타코드 아님.
    {
        quote_plus('ServiceKey') : My_API_Key,    # 필수 항목 1 : 서비스키 (본인의 서비스키)
        quote_plus('LAWD_CD') : '11110',          # 필수 항목 2 : 지역코드 (법정코드목록조회에서 확인)
        quote_plus('DEAL_YMD') : '201512'         # 픽수 항목 3 : 계약월
     }
)

response = requests.get(xmlUrl + queryParams).text.encode('utf-8')
xmlobj = bs4.BeautifulSoup(response, 'lxml-xml')
# xmlobj    # 디버깅용.

rows = xmlobj.findAll('item')
# rows    # 디버깅용.
columns = rows[0].find_all()
# columns    # 디버깅용.
# columns[0].name    # 디버깅용.
# columns[0].text    # 디버깅용.

# 모든 행과 열의 값을 모아 매트릭스로 만들어보자.
rowList = []
nameList = []
columnList = []

rowsLen = len(rows)
for i in range(0, rowsLen):
    columns = rows[i].find_all()
    
    columnsLen = len(columns)
    for j in range(0, columnsLen):
        # 첫 번째 행 데이터 값 수집 시에만 컬럼 값을 저장한다. (어차피 rows[0], rows[1], ... 모두 컬럼헤더는 동일한 값을 가지기 때문에 매번 반복할 필요가 없다.)
        if i == 0:
            nameList.append(columns[j].name)
        # 컬럼값은 모든 행의 값을 저장해야한다.    
        eachColumn = columns[j].text
        columnList.append(eachColumn)
    rowList.append(columnList)
    columnList = []    # 다음 row의 값을 넣기 위해 비워준다. (매우 중요!!)
    
result = pd.DataFrame(rowList, columns=nameList)
result.head()

+ Recent posts