kyejin0412 님의 블로그
Week 13-2 실전 프로젝트 - 스타벅스 한국 매장 지도 크롤링, 맵 시각화 본문
나랑 조장님이 크롤링 팀, 나머지 두분이 EDA 및 전처리팀이 되어, 저녁 전까지는 크롤링과 맵 시각화를 했다.
오늘 한 크롤링 과정을 정리해본다.
크롤링 후보 정리
먼저, 어떤 데이터를 크롤링하면 좋을지 논의한 결과, 다음의 후보가 나왔다.
- 평점 KPI, 바 순위 차트 : 구글 플레이 앱 - 미국 스타벅스 앱(3만개) 리뷰 / 한국 앱(2.97만개) 리뷰 (평점) 3년치 최근 리뷰 (평점) [완료] - 원의님 크롤링
- 바 순위 차트, 파이차트 등 : 스타벅스 한국(메뉴/영양정보, 프로모션 정보), 미국 홈페이지 (메뉴/영양정보, 프로모션 정보) -> 스타벅스 한국 메뉴는 소현튜터님이 크롤링을 해주심. 미국 웹사이트는 보안이 강해서 api 사용해야하는데 유료라 포기함.
- 맵 차트 : 매장 종류별 위치 > 한국 [완료] -> 미국은 위와 같은 이유로 포기했다.
- 가능하면 : 한국 스벅 프로모션 만족도 -> 프로모션 리뷰를 얻기위해 네이버지도 리뷰, 유튜브 리뷰 등을 생각해보았으나 영상마다 편향적이었고, 적절한 영상을 찾기 어려웠다. 리뷰데이터는 비정형이라 전처리도 어려울 듯하여 포기했다.
스타벅스 한국 매장 크롤링
나는 스타벅스 한국 매장 크롤링을 맡았다.
1. 스타벅스 홈페이지 접속
2. [스토어] 메뉴 -> 드라이브 스루 매장, 리저브 매장, 커뮤니티 스토어 매장 순으로 크롤링
https://www.starbucks.co.kr/store/store_drive.do
스타벅스 커피 코리아
스타벅스 커피 코리아
www.starbucks.co.kr
3. SSR 방식으로 했을 때 빈 배열이 반환되었고, 새로고침했을 때 데이터가 뒤늦게 불러와지는 것을 보아 CSR일 것으로 판단
4. CSR 방식으로 크롤링 진행하기로 결정
5. 개발자 도구(F12)를 켜고 새로고침(F5)
6. Network -> Preview 에서 어떤 이름으로 데이터가 받아와지는지 확인 가능.
여기선 getStore.do 로 받아옴. 원하는 정보인 위도, 경도 정보 있는 것 확인

7. getStore.do 마우스 오른쪽 -> Copy -> 윈도우는 Copy as cURL(bash)

8. https://curlconverter.com/ 이 사이트에 복붙하면 파이썬 코드가 나옴.
curl command에 복붙 -> 아래 칸에 import requests로 시작하는 코드 복사

9. vscode에서 붙여넣기 하여 실행. 여기서부터는 코드로 기록하겠다.
# 필요한 라이브러리 import
import requests
import pandas as pd
# 위 사이트에서 복붙한 코드
cookies = {
'_xm_webid_1_': '428745352',
'Vgj0niUP': 'A5cdi62bAQAAXYOTWHpDVQSqsjPKsAaJ5ulNKa1h2JA9pJKJVrv7ePPJbGzQAT1KJyiucmbRwH8AAEB3AAAAAA|1|0|2112972d4c0a274accc6c919d2790443b070ab22',
'PCID': '17681431342675798522039',
'RC_COLOR': '24',
'_ga': 'GA1.3.1407002189.1768143135',
'_gid': 'GA1.3.1201211856.1768268160',
'MENU_CATE': 'product_cold_brew',
'ktlvDW7IG5ClOcxYTbmY': 'a',
'JSESSIONID': 'Le11MtefAu50LDOrT1LB1Vje3fa4kiXkndTCGDMZeRf3ZrDItZo89vS27sp5EvyY.aHBfZG9tYWluL21lbG9uMDM=',
'_gat': '1',
'RC_RESOLUTION': '412*915',
'_ga_WC8Q3C59QP': 'GS2.3.s1768286766$o5$g0$t1768286766$j60$l0$h0',
}
headers = {
'Accept': 'application/json, text/javascript, */*; q=0.01',
'Accept-Language': 'ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7',
'Connection': 'keep-alive',
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
'Origin': 'https://www.starbucks.co.kr',
'Referer': 'https://www.starbucks.co.kr/store/store_drive.do',
'Sec-Fetch-Dest': 'empty',
'Sec-Fetch-Mode': 'cors',
'Sec-Fetch-Site': 'same-origin',
'User-Agent': 'Mozilla/5.0 (Linux; Android 13; Pixel 7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Mobile Safari/537.36',
'X-Requested-With': 'XMLHttpRequest',
'sec-ch-ua': '"Google Chrome";v="143", "Chromium";v="143", "Not A(Brand";v="24"',
'sec-ch-ua-mobile': '?1',
'sec-ch-ua-platform': '"Android"',
# 'Cookie': '_xm_webid_1_=428745352; Vgj0niUP=A5cdi62bAQAAXYOTWHpDVQSqsjPKsAaJ5ulNKa1h2JA9pJKJVrv7ePPJbGzQAT1KJyiucmbRwH8AAEB3AAAAAA|1|0|2112972d4c0a274accc6c919d2790443b070ab22; PCID=17681431342675798522039; RC_COLOR=24; _ga=GA1.3.1407002189.1768143135; _gid=GA1.3.1201211856.1768268160; MENU_CATE=product_cold_brew; ktlvDW7IG5ClOcxYTbmY=a; JSESSIONID=Le11MtefAu50LDOrT1LB1Vje3fa4kiXkndTCGDMZeRf3ZrDItZo89vS27sp5EvyY.aHBfZG9tYWluL21lbG9uMDM=; _gat=1; RC_RESOLUTION=412*915; _ga_WC8Q3C59QP=GS2.3.s1768286766$o5$g0$t1768286766$j60$l0$h0',
}
params = {
'r': '19R7PARXS5',
}
data = {
'ins_lat': '37.56682',
'ins_lng': '126.97865',
'search_text': '',
'p_sido_cd': '',
'p_gugun_cd': '',
'isError': 'true',
'in_distance': '500',
'T03': '0',
'T01': '1',
'T12': '0',
'T09': '0',
'T06': '0',
'T10': '0',
'P10': '0',
'P50': '0',
'P20': '0',
'P60': '0',
'P30': '0',
'P70': '0',
'P40': '0',
'P80': '0',
'T20': '0',
'T22': '0',
'T29': '0',
'new_bool': '0',
'in_biz_cd': '',
'searchType': 'A',
'set_date': '',
'iend': '1000',
'rndCod': 'Q7T3GQ7V52',
}
response = requests.post('https://www.starbucks.co.kr/store/getStore.do', params=params, cookies=cookies, headers=headers, data=data)
# 출력하여 형태 확인
print(response.json())
# json은 딕셔너리 형식이므로, key(key='list')를 가져와서 리스트화 한다.
stores_list = response.json().get('list', [])

# 데이터 분석을 해야하니 판다스를 이용해서 데이터프레임화 해준다.
df = pd.DataFrame(stores_list)
# 필요한 컬럼인 매점명, 도로명주소, 위도, 경도만 추출한다.
df_filtered = df[['s_name', 'doro_address', 'lat', 'lot']]
# 컬럼명을 알기 쉽게 바꿔준다.
columns_mapping = {
's_name': 'store_name',
'lat': 'latitude',
'lot': 'longitude'
}
df_final = df_filtered.rename(columns=columns_mapping)
# 가공 완료된 파일을 csv 파일로 저장한다.
df_final.to_csv("drive_thru_map_list.csv")
print("드라이브 스루 파일 저장 완료")
위 과정을 드라이브 스루 매장, 리저브 매장, 커뮤니티 스토어 매장 모두 반복해서 크롤링했다.
회고
크롤링을 하면서 어려웠던 점 첫번째로는, 크롤링 후보를 정하는 것이었다. 우리가 미국 본사 입장이어서 미국 데이터를 끌어오려하니, 강력한 사이트 보안, 비싼 api, 혹은 회사가 데이터를 제공하지 않는 한계가 있었다.
리뷰 데이터 같은 것은 리뷰가 모아져있는 곳이나, 평점이 있는 곳이면 모으기 수월했는데 텍스트 리뷰는 모으고 전처리하는 것 모두 막막했다. 결국 안하기로 하고, 할 수 있는 범위 내에서 최대한 많이 뽑아내자는 결론이 나왔다.
두번째는, 크롤링 방법이었다. 제미나이한테 물어보니 selenium을 설치하거나 api를 사용하라고 했다. api를 찾아봤을 때 계속 말했듯 비싼 api 이던가, 아예 데이터셋을 제공하지 않았다. 그래서 직접 크롤링 하기로 했다. 이를 위해서는 selenium과 webdriver_manager를 설치하라고 했는데 설치가 잘 되지 않았다.
따라서 크롤링 세션 자료를 찾아보고 따라했는데, 정말 금방 되었다.... SSR과 CSR을 구분하는 실습도 하게 된 것 같아 좋았다.
세션 자료를 믿자!
세번째는, 태블로 데이터 연결이었다. 아직 태블로 데이터를 연결하는게 미숙하다는 것을 깨달았다. 그동안 실습에서는 데이터 하나만 썼던 것 같은데, 이번엔 지도 데이터 3개였고, 원본 데이터도 3개가 있었다. 이를 모두 올리고 시작하니 다중연결에서 문제가 발생한다는 알림 도착..... 하나의 대시보드에 하는게 안되나 싶어서 일단 지도 데이터 하나씩 올려서 시각화했다.

마지막 스크럼 때 다른 팀원이 이 세 파일을 유니온 해서 하나의 맵에 시각화 하면 좋을 것 같다는 의견을 주었다.
듣고 보니 구분 컬럼을 추가하여 유니온하면 하나의 맵으로 만들 수 있을 것 같다! 역시 도움을 받아야 한다...
내일은 오전에 맵 데이터를 유니온해서 시각화를 마저 해보고, 데이터셋을 확인해 볼 예정이다. (오늘은 크롤링과 태블로와 싸우다가 데이터셋을 못 봤다 ㅜㅜ)
마케팅 데이터 분석이 꽤 재미있을 것 같단 기대가 된다.
'내일배움캠프-데이터분석' 카테고리의 다른 글
| Week 13-4 실전 프로젝트 - 대시보드 기획 (0) | 2026.01.16 |
|---|---|
| Week 13-3 실전 프로젝트 - 마케팅 주요 데이터 분석 정리 (1) | 2026.01.15 |
| Week 13-1 실전 프로젝트 - 주제 정하기 (1) | 2026.01.12 |
| Week 12-7 크롤링 (2) | 2026.01.11 |
| Week 11-5 태블로 시작 (0) | 2026.01.02 |