직방에서 서울 아파트 정보 크롤링하기 #1

채병주·2021년 1월 16일
1

Toy Project

목록 보기
1/1

얼마 전 작은 프로젝트에 보조연구원으로 참여하게 되었다. 내가 맡은 작업은 직방이라는 부동산 사이트에서 서울 지역 아파트 단지에 대한 정보를 크롤링하는 것이었다. 프로젝트를 진행한 내용을 간단하게 정리해보고자 한다.

1. 크롤링 단위 설정하기

1) geohash 이용하여 아파트 정보 얻기

가장 먼저 진행해야 하는 작업은 검색 범위(서울 지역)에 포함되는 단지들의 개수 및 종류를 확인하는 작업이었다. 대부분의 크롤링 관련 포스팅에서는 직방이 geohash 라는 지리 정보 인덱스를 입력받아 그 위치에 해당하는 정보를 리턴한다고 이야기를 하였고, 실제로 그렇게 진행하였다. geohash 로 진행하는 크롤링은 아래 reference들을 참고하면 될 것 같다. 처음에는 reference 대로 크롤링을 진행하였는데 몇 가지 문제점이 발생하였다.

  1. 서울시는 정확하게 정사각형으로 구분되지 않는다. 그렇다보니 서울 내의 모든 아파트를 확인하기 위해서는 서울시를 일부라도 포괄하는 geohash 값을 넣고, 서울시가 아닌 아파트들을 한 번 필터링해야하는 데 조금 비효율적이라고 생각하였다.

  2. geohash 가 지역을 나누는 기준이 쉽게 이해되지 않았다. 내가 진행한 방법이 아니기 때문에 짧게만 이야기하자면, 하나의 구역을 재귀적으로 16등분하여 인덱싱을 진행하는 것이다. 예를 들어 aaa 라는 geohash 값이 할당된 지역은 aaaa, aaab 와 같은 방법으로 총 32개의 소구역으로 분할할 수 있다. (알파벳은 정확하지 않을 수 있다.)

포장해서 말하면 효율적인 방법이 아니라서. 솔직하게 말하면 인덱싱 방법을 온전히 이해하지 못해서 이 방법을 사용하지 못했다. geohash 에 대해 더 궁금하다면 첫번째 레퍼런스[1] 를 참조하는 것을 추천한다.

2) 시군구 코드를 통해 아파트 정보 얻기

아파트 정보를 얻는 방법에 대해 고민하던 도중 한가지 의문을 품게 되었다.

위의 이미지는 직방에서 '성북구'를 검색하였을 때 나오는 페이지이다. 직방 내의 지도를 조금만 축소하면 이렇게 구 단위로 정보를 얻을 수가 있다. 오른쪽 탭을 보면 성북구 내의 아파트에 대한 다양한 정보가 포함되어 있다. 따라서 구 단위로 크롤링을 진행하면 되지 않을까란 생각을 하였다. 이 생각을 가지고 확인을 해보니, 성북구를 검색했을 때의 URL이 눈에 들어왔다. 이미지의 URL을 확인해보면 성북구의 경우 https://www.zigbang.com/home/apt/locals/11290 와 같은 주소를 가지고 있다. 찾아보니 11290 이란 숫자는 '시군구 코드' 라고 한다. 따라서 이 시군구 코드를 기반으로 크롤링을 진행하기로 했다. 서울시에는 총 25개의 구가 존재하며, 시군구 코드는 해당 링크 에서 csv 파일을 다운 받아 이용할 수 있다. 해당 파일을 다운 받아서 구 이름과 코드를 각각 key와 value로 가지는 json 파일을 만들어 저장했다. 이후 python 코드 내에서 dictionary 타입으로 저장하여 크롤링을 진행하였다.

2. 개발자 도구에서 필요한 Request URL 찾기

이제 직방에서 각 구 별로 검색을 진행하는 방법을 찾았으니 개발자 도구를 이용하여 어떤 식으로 아파트 정보를 얻을 수 있는지 확인해보았다. 여기서 작은 팁 아닌 팁이라면, 크롤링을 진행할 때 얻고 싶은 정보가 있다면 개발자 도구 내의 Network 탭에서 XHR 만 필터링해보자. XHR은 'Xml Http Request'의 약자로, 해당 정보만 필터링하면 브라우저에서 서버와 비동기 통신을 할 때 브라우저가 서버로 전달하는 Request와 Response를 확인할 수 있다. 이렇게 필터링을 하고나면, 'Preview'를 통해서 각 Response가 무엇을 의미하는지 확인하자.


위의 이미지는 성북구를 검색했을 때 확인한 Response 중 하나다. 해당 json 파일 내에서 count 는 성북구 내의 아파트 단지 개수를, 그리고 ids 는 성북구 내의 아파트 단지의 고유 id 값임을 확인할 수 있다. 그런데 왜 아파트 단지는 5개 밖에 반환되지 않았을까? 이건 Request의 parameter를 확인하면 알 수 있다. 아래 이미지는 위의 데이터에 대한 Header 정보이다.

여기서 중요한 건 바로 'Request URL' 이다. URL의 parameter를 하나씩 살펴보자.

  • type=local : 검색을 진행하는 기준을 나타내는 것이다. 지역 단위 검색인지, geohash 단위 검색인지와 같은 것을 결정하는 것 같다.
  • id=11290 : 성북구의 시군구 코드이다. 위의 type parameter에 따라서 id 값의 역할이 바뀌지 않을까 싶다.
  • limit=5 : 아파트 고유 id 값이 5개만 반환된 이유다. 아파트 고유 id 개수를 5개로 제한한다는 뜻이다.
  • order=viewCount : 아파트 고유 id 정렬 방식을 의미할 것이다.

3. 하위 단위 별로 아파트 단지 고유 id 추출 함수 작성하기

serviceType[0]=aptserviceType[1]=offer 는... 잘 모르겠다.... 😂 아마 serviceType[1] 은 거래 방식(ex. 전세, 월세, 등등...)을 나타내는 것이 아닐까 싶다. 이런 경우 각 parameter를 지워보거나, 수정해보면서 어떤 값들이 반환되는지를 확인하면서 각 parameter의 역할을 확인할 수 있다. 하지만, 위의 4개 parameter만 확인해봐도, type , id , limit 3가지 parameter만을 가지고도 원하는 결과를 얻을 수 있지 않을까라는 생각이 들었다. 이런 자신감을 바탕으로 하나의 구에 속해있는 아파트 단지 id를 전부 찾아서 list 타입으로 반환하는 함수를 만들어보자.

# local은 각 구의 시군구 코드
def findApartmentsID(local):
    url = "https://apis.zigbang.com/property/biglab/apartments/list?type=local&id={localId}"
    req = requests.get(url.format(localId=guId))
    info = req.json()
    
    result = info['ids']
    print(info['count']
    return result

위의 함수에 시군구 코드를 인자로 넘겨줘서 실행하면 총 아파트 단지 수(info['count'])를 출력하고, 해당 지역의 아파트들의 고유 id 값을 list 형식으로 반환한다. 적어도 하나의 구에 속해있는 아파트 단지들의 고유 id 값을 추출하는 것에 성공하였음을 확인할 수 있다. 해당 함수를 각 구에 대해서 반복하여 실행하면 서울시 전체의 아파트 단지 고유 id 값을 확인할 수 있다. 다음 포스팅에서는 아파트 단지 고유 id를 바탕으로 기본 정보들을 추출하는 과정에 대해서 글을 써보고자 한다.

4. Reference

  1. 자연어 처리 #3 직방의 지리정보 Geohash 이해하기 [link]
  2. 자연어 처리 #4 직방 아파트ID 얻기 [link]
  3. 자연어 처리 #5 직방 부동산 평가 크롤링하기 [link]
  4. 바쁜 개발자가 집 알아보는 방법 [link]
profile
개발 외의 일들에 더 흥미를 가지는 개발자. Interested in Web, Generative AI, UI/UX.

0개의 댓글