부동산 - 네이버 부동산 크롤링
http://land.naver.com 의 검색 인자는 다음과 같이 구성
- rletTypeCd: A01=아파트, A02=오피스텔, B01=분양권, 주택=C03, 토지=E03, 원룸=C01, 상가=D02, 사무실=D01, 공장=E02, 재개발=F01, 건물=D03
- tradeTypeCd (거래종류): all=전체, A1=매매, B1=전세, B2=월세, B3=단기임대
- hscpTypeCd (매물종류): 아파트=A01, 주상복합=A03, 재건축=A04 (복수 선택 가능)
- cortarNo(법정동코드): (예: 1168010600 서울시, 강남구, 대치동)
※ 법정동 코드에 대한 상세내용은 https://goo.gl/P6ni8Q 참조
사이 문자열 검색¶
정규식을 사용하여 특정 문자열 사이에 있는 문자열을 얻는다
In [1]:
import re
text = '220/191공급면적220.92㎡전용면적191.06㎡'
공급면적 = re.findall('공급면적(.*?)㎡', text)[0]
전용면적 = re.findall('전용면적(.*?)㎡', text)[0]
print('공급면적: ', 공급면적)
print('전용면적: ', 전용면적)
In [2]:
import re
import pandas as pd
from datetime import datetime
from bs4 import BeautifulSoup
import requests
url = 'http://land.naver.com/article/articleList.nhn?rletTypeCd=A01&tradeTypeCd=A1&hscpTypeCd=A01%3AA03%3AA04&cortarNo=1168010600'
r = requests.get(url)
soup = BeautifulSoup(r.text, 'lxml')
table = soup.find('table')
trs = table.tbody.find_all('tr')
# 거래, 종류, 확인일자, 매물명, 면적(㎡), 층, 매물가(만원), 연락처
for tr in trs[::2]:
tds = tr.find_all('td')
cols = [' '.join(td.text.strip().split()) for td in tds]
if '_thumb_image' not in tds[3]['class']: # 현장확인 날짜와 이미지가 없는 행
cols.insert(3, '')
거래 = cols[0]
종류 = cols[1]
확인일자 = datetime.strptime(cols[2], '%y.%m.%d.')
현장확인 = cols[3]
매물명 = cols[4]
면적 = cols[5]
공급면적 = re.findall('공급면적(.*?)㎡', 면적)[0].replace(',', '')
전용면적 = re.findall('전용면적(.*?)㎡', 면적)[0].replace(',', '')
공급면적 = float(공급면적)
전용면적 = float(전용면적)
층 = cols[6]
매물가 = int(cols[7].replace(',', ''))
연락처 = cols[8]
print(거래, 종류, 확인일자, 현장확인, 매물명, 공급면적, 전용면적, 층, 매물가, 연락처)
함수로 만들기¶
앞에서 확인된 내용으로 재사용 가능한 함수를 만든다
In [3]:
import re
import numpy as np
import pandas as pd
import requests
from datetime import datetime
from bs4 import BeautifulSoup
def get_naver_realasset(area_code):
url = 'http://land.naver.com/article/articleList.nhn?' \
+ 'rletTypeCd=A01&tradeTypeCd=A1&hscpTypeCd=A01%3AA03%3AA04' \
+ '&cortarNo=' + area_code
r = requests.get(url)
soup = BeautifulSoup(r.text, 'lxml')
table = soup.find('table')
trs = table.tbody.find_all('tr')
value_list = []
# 거래, 종류, 확인일자, 매물명, 매물명, 면적(㎡), 층, 매물가(만원), 연락처
for tr in trs[::2]:
tds = tr.find_all('td')
cols = [' '.join(td.text.strip().split()) for td in tds]
if '_thumb_image' not in tds[3]['class']: # 현장확인 날짜와 이미지가 없는 행
cols.insert(3, '')
거래 = cols[0]
종류 = cols[1]
확인일자 = datetime.strptime(cols[2], '%y.%m.%d.')
현장확인 = cols[3]
매물명 = cols[4]
면적 = cols[5]
공급면적 = re.findall('공급면적(.*?)㎡', 면적)[0].replace(',', '')
전용면적 = re.findall('전용면적(.*?)㎡', 면적)[0].replace(',', '')
공급면적 = float(공급면적)
전용면적 = float(전용면적)
층 = cols[6]
매물가 = int(cols[7].replace(',', ''))
연락처 = cols[8]
value_list.append([거래, 종류, 확인일자, 현장확인, 매물명, 공급면적, 전용면적, 층, 매물가, 연락처])
cols = ['거래', '종류', '확인일자', '현장확인', '매물명', '공급면적', '전용면적', '층', '매물가', '연락처']
df = pd.DataFrame(value_list, columns=cols)
return df
In [4]:
df = get_naver_realasset('1168010600')
df
Out[4]:
페이지 처리¶
요청 url 에 "&page=페이지번호" 인자를 추가하여 페이지를 처리한다.
In [5]:
import re
import numpy as np
import pandas as pd
import requests
from datetime import datetime
from bs4 import BeautifulSoup
def get_naver_realasset(area_code, page=1):
url = 'http://land.naver.com/article/articleList.nhn?' \
+ 'rletTypeCd=A01&tradeTypeCd=A1&hscpTypeCd=A01%3AA03%3AA04' \
+ '&cortarNo=' + area_code \
+ '&page=' + str(page)
r = requests.get(url)
soup = BeautifulSoup(r.text, 'lxml')
table = soup.find('table')
trs = table.tbody.find_all('tr')
if '등록된 매물이 없습니다' in trs[0].text:
return pd.DataFrame()
value_list = []
# 거래, 종류, 확인일자, 매물명, 면적(㎡), 층, 매물가(만원), 연락처
for tr in trs[::2]:
tds = tr.find_all('td')
cols = [' '.join(td.text.strip().split()) for td in tds]
if '_thumb_image' not in tds[3]['class']: # 현장확인 날짜와 이미지가 없는 행
cols.insert(3, '')
# print(cols)
거래 = cols[0]
종류 = cols[1]
확인일자 = datetime.strptime(cols[2], '%y.%m.%d.')
현장확인 = cols[3]
매물명 = cols[4]
면적 = cols[5]
공급면적 = re.findall('공급면적(.*?)㎡', 면적)[0].replace(',', '')
전용면적 = re.findall('전용면적(.*?)㎡', 면적)[0].replace(',', '')
공급면적 = float(공급면적)
전용면적 = float(전용면적)
층 = cols[6]
if cols[7].find('호가일뿐 실거래가로확인된 금액이 아닙니다') >= 0:
pass # 단순호가 별도 처리하고자 하면 내용 추가
매물가 = int(cols[7].split(' ')[0].replace(',', ''))
연락처 = cols[8]
value_list.append([거래, 종류, 확인일자, 현장확인, 매물명, 공급면적, 전용면적, 층, 매물가, 연락처])
cols = ['거래', '종류', '확인일자', '현장확인', '매물명', '공급면적', '전용면적', '층', '매물가', '연락처']
df = pd.DataFrame(value_list, columns=cols)
return df
In [6]:
df = get_naver_realasset('1168010600', 60) # 60 페이지
df
Out[6]:
페이지묶어 DataFrame 생성하기¶
페이지별로 생성된 DataFrame 을 묶어(append) 하나의 DataFrame으로 합친다
In [7]:
area_code = '1168010600' # 강남구, 대치동 (법정동 코드 https://goo.gl/P6ni8Q 참조)
df = pd.DataFrame()
for i in range(1, 100): # 최대 100 페이지
df_tmp = get_naver_realasset(area_code, i)
if len(df_tmp) <= 0:
break
df = df.append(df_tmp, ignore_index=True)
df.head()
Out[7]:
In [8]:
'강남구, 대치동(1168010600)의 물건 총 %d건' % len(df)
Out[8]:
In [9]:
df.tail()
Out[9]:
댓글
Comments powered by Disqus