[파이썬 크롤링/부동산 데이터] scrapy를 이용한 부동산 공공 데이터 저장하기(csv/excel)

| 들어가기 전에


GIT 저장소


지금 포스팅은 국토교통부에서 제공하는 부동산 공공데이터 API를 사용합니다. 아래 포스팅을 보시고 먼저 부동산 공공데이터 API를 신청해주시길 바래요!


[유용한 정보들] - 국토교통부 공공데이터 부동산 실거래가 API 신청 방법



이전 포스팅


[파이썬/파이썬 웹 크롤링 - 부동산 공공데이터] - [파이썬 크롤링/부동산 데이터] 스크래피(scrapy) startproject로 초기 프로젝트 구성하기

[파이썬/파이썬 웹 크롤링 - 부동산 공공데이터] - [파이썬 크롤링/부동산 데이터] scrapy를 이용한 부동산 공공 데이터 간단하게 받아오기

[파이썬/파이썬 웹 크롤링 - 부동산 공공데이터] - [파이썬 크롤링/부동산 데이터] scrapy를 이용한 부동산 공공 데이터 파싱 및 추출하기



포스팅에 있는 내용을 따라하기 위해서는 pandas 패키지를 설치해야합니다. pandas는 파이썬에서 사용하는 데이터분석 라이브러리로, 행과 열로 이루어진 데이터 객체를 만들어 다룰 수 있게 되며 보다 안정적으로 대용량의 데이터들을 처리하는데 매우 편리한 도구 입니다. 


pandas의 DataFrame 자료구조를 이용해서 파이썬의 객체들을 csv파일 혹은 excel 파일로 쉽게 저장할 수 있습니다. 또한 DataFrame을 통해 excel 파일로 데이터를 저장하기 위한 엔진이 필요한데, 이를 위해서 xlsxwriter 패키지도 같이 설치해줘야 합니다.


pip install pandas xlsxwriter



|  Pandas를 이용해서 공공데이터를 csv, excel 형태로 저장하기



프로젝트 구조

| scrapy.cfg
\---invest_crawler
| consts.py
| settings.py
| __init__.py
|
+---items
| | apt_trade.py
| | __init__.py
|
+---spiders
| | apt_trade_spiders.py
| | __init__.py


소스 코드


consts.py

# 샘플 더미 데이터 입니다. 어떻게 세팅하는 지 보여드리기 위해 넣은 데이터이기 때문에 그대로 사용하시면 에러가 납니다.
APT_DETAIL_ENDPOINT = "http://openapi.molit.go.kr:8081/OpenAPI_ToolInstallPackage/service/rest/RTMSOBJSvc/getRTMSDataSvcAptTrade?serviceKey=asdsdfsdfWiZGAJkCsr3wM0YkDO%2BssYpNXZ%2FEWZfuIW5k%2FcHFtD5k1zcCVasdfEtBQID5rIcjXsg%3D%3D&"


apt_trade.py

import scrapy


class AptTradeScrapy(scrapy.Item):

apt_name = scrapy.Field()
address_1 = scrapy.Field()
address_2 = scrapy.Field()
address_3 = scrapy.Field()
address_4 = scrapy.Field()
address = scrapy.Field()
age = scrapy.Field()
level = scrapy.Field()
available_space = scrapy.Field()
trade_date = scrapy.Field()
trade_amount = scrapy.Field()

def to_dict(self):
return {
'아파트': self['apt_name'],
'시/도': self['address_1'],
'군/구': self['address_2'],
'동/읍/면': self['address_3'],
'번지': self['address_4'],
'전체주소': self['address'],
'연식': self['age'],
'층': self['level'],
'면적': self['available_space'],
'거래일자': self['trade_date'],
'매매가격': self['trade_amount']
}
  • to_dict 메서드를 AptTradeScrapy item에 추가하였습니다. 이 메서드를 작성한 목적은 pandas에서 지원하는 DataFrame 자료구조로 item을 쉽게 변환하기 위해 추가한 것입니다. 
  • 여기서 조금 헷갈리실 수 있는 부분은 to_dict에서 self 키워드일 것입니다. 이 self 키워드는 객체 자기자신을 나타냅니다. scrapy에서 item의 속성값은 [ ] 같이 대괄호를 통해 접근할 수 있습니다. 따라서 자기자신을 나타내는 키워드인 self에 [ ] 안에 속성명을 집어넣어 데이터를 구성하는 것입니다.  



apt_trade_spiders.py

import datetime as dt
from urllib.parse import urlencode

import scrapy
from scrapy import Selector

import invest_crawler.consts as CONST
from invest_crawler.items.apt_trade import AptTradeScrapy

import pandas as pd


class TradeSpider(scrapy.spiders.XMLFeedSpider):
name = 'trade'

def start_requests(self):
page_num = 1
date = dt.datetime(2006, 1, 1)
urls = [
CONST.APT_DETAIL_ENDPOINT
]
params = {
"pageNo": str(page_num),
"numOfRows": "999",
"LAWD_CD": "44133",
"DEAL_YMD": date.strftime("%Y%m"),
}
for url in urls:
url += urlencode(params)
yield scrapy.Request(url=url)

def parse(self, response):
selector = Selector(response, type='xml')
items = selector.xpath('//%s' % self.itertag) # self.intertag는 기본적으로 item으로 되어 있음

apt_trades = [self.parse_item(item) for item in items]
apt_dataframe = pd.DataFrame.from_records([apt_trade.to_dict() for apt_trade in apt_trades])

writer = pd.ExcelWriter('APT_TRADE.xlsx', engine='xlsxwriter')
apt_dataframe.to_excel(writer, sheet_name='Cheonan', index=False)
writer.save()

def parse_item(self, item):
state = "천안시"
district = "서북구"

try:
apt_trade_data = AptTradeScrapy(
apt_name=item.xpath("./아파트/text()").get(),
address_1=state,
address_2=district,
address_3=item.xpath("./법정동/text()").get().strip(),
address_4=item.xpath("./지번/text()").get(),
address=state + " " + district + " " + item.xpath("./법정동/text()").get().strip() + " " +
item.xpath("./지번/text()").get(),
age=item.xpath("./건축년도/text()").get(),
level=item.xpath("./층/text()").get(),
available_space=item.xpath("./전용면적/text()").get(),
trade_date=item.xpath("./년/text()").get() + "/" +
item.xpath("./월/text()").get() + "/" +
item.xpath("./일/text()").get(),
trade_amount=item.xpath("./거래금액/text()").get().strip().replace(',', ''),
)

except Exception as e:
print(e)
self.logger.error(item)
self.logger.error(item.xpath("./아파트/text()").get())

return apt_trade_data
  • 아래 코드에서는 파이썬의 LC(List Comprehension)을 통해 파이썬의 리스트에 담길 item들을 손쉽게 구성하는 것을 볼 수 있습니다.
    apt_trades = [self.parse_item(item) for item in items]
  • 또한 위에서 정의해둔 to_dict 메서드를 통해 파이썬 객체 리스트를 손쉽게 pandas에서 제공하는 DataFrame 자료구조로 변환하는 모습입니다.
    apt_dataframe = pd.DataFrame.from_records([apt_trade.to_dict() for apt_trade in apt_trades])
  • DataFrame으로 자료를 구성했다면 DataFrame에서 제공하는 저장기능으로 csv 혹은 excel 파일 형식으로 손쉽게 저장할 수 있습니다. 저장하는 코드는 아래와 같습니다. 파일 이름과 sheet_name을 지정하는 것을 눈여겨 봐주셔야 합니다.

    writer = pd.ExcelWriter('APT_TRADE.xlsx', engine='xlsxwriter')
    apt_dataframe.to_excel(writer, sheet_name='Cheonan', index=False)
    writer.save()



결과 화면




다음 포스팅에는 scrapy를 통해 공공데이터를 어떻게 연속적으로 쉽게 가져올 수 있을 지를 보겠습니다.

이 글을 공유하기

댓글(0)

Designed by JB FACTORY