-
[Python] 네이버 부동산 매물 크롤링Programming 2022. 11. 5. 15:08
오랜만에 포스팅한다.
친구들과 마이너스 피에 대해 이야기를 나누다가, 네이버 부동산에서 매물을 크롤링해 투자 물건지를 찾을 수는 없을까 하는 생각이 들었다.
그래서 오늘은 초반에 매물을 크롤링해오는 부분을 먼저 다루려한다.
진행 과정은 아래와 같다.
1. 지역 선택
2. 해당 지역의 위치 정보(좌표) 찾기
3. 해당 위치의 매물 크롤링(20개씩 크롤링 가능)
4. 크롤링한 정보에서 필요한 정보 추출 및 정리
* 크롤링에는 네이버 부동산 모바일 페이지를 사용 (http://m.land.naver.com)하나씩 차근차근 살펴보자.
1. 지역 선택
- 네이버 부동산 모바일 페이지에서는 아래와 같은 화면으로 지역을 세분화해서, 매물을 관리하고 있다.
- 경상북도 구미시를 예시로 코드를 작성했으니 참고
네이버 부동산 지역 2. 선택한 지역의 위치 정보 확인
- 실제로 호출되는 URL을 살펴보면, 지역별로 위도(latitude)와 경도(longitude) 정보가 포함되어 있는 것을 알 수 있다.
- 그런데 우리는 시/구/동 별로 모든 위도, 경도 정보를 알고 있지 않기 때문에 아래와 같이 지역명을 이용하려 한다.
import requests import numpy as np import pandas as pd keyword = '경상북도 구미시' url = 'https://m.land.naver.com/search/result/' + keyword + '#mapFullList' headers = {'User-Agent':"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36"} res = requests.get(url, headers=headers) print(res.url)
- 지역명으로 만든 url 을 호출하고, res.url 을 프린트해보면 아래와 같은 결과를 확인할 수 있다.
- 지역명이 위도와 경도 정보로 변환되었음을 알 수 있다. (위도: 36.119549, 경도 128.344188, 지역코드: 4719000000)
위도 경도 정보 변환 URL - 여기서 우리가 원하는 정보를 추출하고, 그 정보로 다시 매물 정보를 추출할 수 있는 URL 을 만들 수 있다.
- 아래 코드는 새로운 URL 을 만들기 위해 필요한 정보를 정의하는 부분이다.
main_url = res.url.split('?')[0] lat = main_url.split('/')[4].split(':')[0] #위도 lon = main_url.split('/')[4].split(':')[1] #경도 z = main_url.split('/')[4].split(':')[2] cortarNo = main_url.split('/')[4].split(':')[3] #지역코드 buildingType = 'APT' #아파트
3. 매물 크롤링
- 이제 매물 정보를 가지고 있는 URL 을 만들어보자.
- URL 을 구성하는 요소들은 다음과 같다.
- rletTpCd: 건물 유형 (아파트, 상가 등)
- tradTpCd: 거래 유형 (A1: 매매, B1: 전세, B2: 월세)
- z 의 의미는 정확하게 모르겠지만, 변수로 들어가 있어서 parsing 해서 활용
- lat: 위도
- lon: 경도
- cortarNo: 지역 코드
- page: 1 페이지에 매물 20개 크롤링 가능
https://m.land.naver.com/cluster/ajax/articleList?rletTpCd={}&tradTpCd=A1%3AB1%3AB2&z={}&lat={}&lon={}&cortarNo={}&page={}'.format(buildingType, z, lat, lon, cortarNo, page)
- 위 예시와 같이 지역별로 page 를 늘려가면서 URL request 를 날리면 우리가 원하는 정보를 수집할 수 있다.
- 예시 URL 에서 반환하는 json 내용을 살펴보면, body 내에 매물에 대한 정보가 포함되어 있는 것을 볼 수 있다.
- 여기서 일부 필요한 데이터만 추출해서 데이터 프레임화 시켜보자.
keyList = ['atclNo', 'atclNm', 'rletTpNm', 'tradTpNm', 'bildNm', 'flrInfo', 'prc', 'sameAddrMaxPrc', 'sameAddrMinPrc', 'sameAddrCnt', 'direction', 'spc1', 'spc2'] #매물번호, 건물명, 건물유형, 거래유형, 동, 해당층/전체층, 가격, 동일 매물 최고 가격, 동일 매물 최저 가격, 동일 매물 개수, 방향, 공급, 전용 def extractList(page): sub_url = 'https://m.land.naver.com/cluster/ajax/articleList?rletTpCd={}&tradTpCd=A1%3AB1%3AB2&z={}&lat={}&lon={}&cortarNo={}&page={}'.format(buildingType, z, lat, lon, cortarNo, page) res = requests.get(sub_url, headers=headers).json() dataList = [] for i in range(len(res['body'])): dataEle = [] for ele in keyList: try: dataEle.append(res['body'][i][ele]) except: dataEle.append('') dataList.append(dataEle) df = pd.DataFrame(dataList, columns=keyList) return df ########### collectDf = [] for i in range(1, 1000): time.sleep(10) df = extractList(i) if df.shape[0] > 0: collectDf.append(df) else: print(i) break newDf = pd.concat(collectDf)
- 대신 주의해야할 점은 연속적으로 많인 request 를 날리면 네이버 자체에서 block 해버린다는 점. 그래서 나는 sleep 으로 일정 시간 텀(time.sleep(10))을 주고 요청하는 것으로 코드를 수정했다.
- 전체 매물이 몇 개인지 알면 매물 개수 / 20 으로 대충 page 수량을 가늠할 수 있겠지만, 해당 정보는 아직 못 찾았다.
4. 크롤링 결과 정리하기
- 위 코드로 추출한 데이터들을 합치게 되면 아래와 같은 데이터 프레임이 생성된다.
- 여기서 아파트, 공급면적(spc1) 별로 최소/최대 가격을 pivot 으로 정리해볼 수 있을 것 같다.
- 그리고 동일 매물이 여러 부동산에 올라오면 sameAddrCnt 라는 항목에 count 가 되는데, 이게 높을 수록 집주인이 빨리 팔고 싶어한다고 볼 수 있지 않을까. (급매 타이틀로 10군데 넘게 올라온 매물도 봄)
수집한 데이터 pivot 결과
이 데이터로 어떤 아파트를 투자물로 삼을 것인지, 투자 금액은 얼마인지 계산하고 추려내는 방법을 또 이제 고민해보자.
끝
'Programming' 카테고리의 다른 글
[Python] 2022 3Q 미국주식 퀀트 분석하기 (0) 2022.12.10 [Python] Yahoo Finance 코드 업데이트 (22.3Q) (0) 2022.12.03 [Python] 지역별 부동산 데이터 시각화 (9) 2022.10.07 [Python] KB 부동산 데이터 수집하기 (4) 2022.10.03 [Python] 퀀트 투자 기법 적용 결과 (한국편) (1) 2022.09.17