본문 바로가기
웹 크롤링(Web Crawling)/크롤링 프로젝트(시행 착오 노트)

json으로 제공되는 데이터 크롤링하기 (API 데이터 크롤링하기)

by 현군의 coding&IT story 2024. 9. 22.

크롤링 요구사항

고방 사이트에서 '쉐어하우스' 에 올라온 집 정보들이 필요했다.

https://m.gobang.kr/share 사이트에서 서울에 있는 모든 정보를 크롤링해야 한다.

 

문제 해결 방안

일반 크롤링 방식으로는 절차가 복잡하고 데이터도 많아 어려워 보였다.

따라서 API를 통해 GET 요청 받은 데이터를 크롤링 하기로 결정하였다.

 

1) 개발자 도구의 Network 탭에서 방들의 정보가 담긴 JSON 파일을 찾는다.

팁이 있다면, Fetch/XHR 에서 찾을 수 있다.

 

사이트를 들어가보면 아래와 같이 뜬다.

찾았다!

그런데 해당 페이지는 스크롤을 내리기 전까지 아래에 있는 데이터를 가져오지 않았다.

그래서 새로운 요청이 또 있을 것이라고 판단!

 

스크롤 내리기 전 요청들
스크롤을 내린 후 요청들 (뭔가 하나 더 생겼다!)


새로 생긴 것의 api 주소를 보니 미세하게 다른 것이 있었다.

주소의 밑줄 친 부분이 미세하게 달랐다.

[처음 화면 요청]
https://api.gobang.kr/v1/houses?%7B%22HOUSE_TYPE_CDS%22%3A%5B%22HOUTP00002%22%5D%2C%22DONGLI_CDS%22%3A%5B%2211%22%5D%2C%22PAGE_NUM%22%3A1%2C%22randomSeed%22%3A5596%7D
[첫 번째 끝까지 스크롤 후 요청]
https://api.gobang.kr/v1/houses?%7B%22HOUSE_TYPE_CDS%22%3A%5B%22HOUTP00002%22%5D%2C%22DONGLI_CDS%22%3A%5B%2211%22%5D%2C%22PAGE_NUM%22%3A2%2C%22randomSeed%22%3A2284%7D
[두 번째 끝까지 스크롤 후 요청]
https://api.gobang.kr/v1/houses?%7B%22HOUSE_TYPE_CDS%22%3A%5B%22HOUTP00002%22%5D%2C%22DONGLI_CDS%22%3A%5B%2211%22%5D%2C%22PAGE_NUM%22%3A3%2C%22randomSeed%22%3A2284%7D

[규칙성] -> A1, A2, A3.... 
f'https://api.gobang.kr/v1/houses?%7B%22HOUSE_TYPE_CDS%22%3A%5B%22HOUTP00002%22%5D%2C%22DONGLI_CDS%22%3A%5B%2211%22%5D%2C%22PAGE_NUM%22%3A{cur_page_num}%2C%22randomSeed%22%3A5596%7D'

 

그런데, 언제까지 받아 올지를 정해야 한다.

그러기 위해서 일단 끝까지 내려서 api를 분석한 결과, A19까지는 "hasMore" 값이 True 였는데, A20부터 "hasMore" 값이 False 이다. 그리고 A21 페이지부터는 데이터가 뜨지 않는다.

즉, hasMore값이 처음으로 False가 되는 지점까지 크롤링하면 되겠다! (쉽게 말해 hasMore은 다음 페이지의 여부이다.)

다음 페이지가 있는 경우 hasMore가 true이다.(1~19페이지)
다음 페이지가 없는 경우 hasMore가 false이다. (20페이지)
21페이지부터는 데이터가 없다.

 

구현

# json 활용
import requests # 크롤링에 사용하는 패키지
from bs4 import BeautifulSoup # html 변환에 사용함
import time
import json

cur_page_num = 1 # 현재 페이지 번호
while(1):
    # 카테고리 데이터 가져오기
    url = f'https://api.gobang.kr/v1/houses?%7B%22HOUSE_TYPE_CDS%22%3A%5B%22HOUTP00002%22%5D%2C%22DONGLI_CDS%22%3A%5B%2211%22%5D%2C%22PAGE_NUM%22%3A{cur_page_num}%2C%22randomSeed%22%3A5596%7D'

    # 헤더정보
    header = {
        'user-agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Mobile Safari/537.36',
        'referer': 'https://m.gobang.kr/share'
    }

    response = requests.get(url, headers=header) # get 요청으로 접속
    if response.status_code == requests.codes.ok:
        print(f'---------{cur_page_num}페이지 접속성공---------')
    else:
        print(f'---------{cur_page_num}페이지 접속실패---------')
    
    json_data = json.loads(response.text) # json파일을 리스트로 받아옴
    #print(json_data)

    # NAME을 추출하는 코드
    for house in json_data["DATA"]:
        print(house["NAME"])

    # 만약 다음 페이지가 없는 경우 (==hasMore 값이 false 인 경우) 페이지 종료
    if json_data["hasMore"] == False:
        break
    else: # 다음 페이지가 있는 경우 다음 페이지 json 데이터 보기
        cur_page_num = cur_page_num + 1


print("============작업 정상 종료!!================")