티스토리 뷰

 

프로젝트 맥락: 이 글은 특정 웹사이트(메가커피)를 대상으로 Selenium BeautifulSoup을 사용해 데이터를 수집하고, pandas로 전처리·병합한 뒤 folium으로 지도 시각화를 구현하는 과정을 학습한 결과입니다. 사이트가 어떤 곳이든, HTML 구조만 분석하면 비슷한 방식으로 크롤링해서 시군구별 통계나 지도 시각화를 해 볼 수 있습니다.


1. 왜 이 코드를 작성했는가?

  • 웹 상에는 API가 아닌 HTML 형태로 공개된 데이터가 많음
  • 단발성 수집이 아니라, 주기적 자동화대규모 수집이 필요할 수 있음
  • 수집한 데이터를 다른 통계(인구, 사업체 수 등)와 병합하여 유의미한 분석 가능
  • GIS(지도) 시각화까지 연동해, 지역별 분포매장 밀집도를 직관적으로 파악

이런 전반적인 과정을 익히기 위해, 특정 사이트(메가커피)를 예시로 삼아 학습 프로젝트를 진행했습니다.


2. 프로젝트 전체 흐름

  1. Selenium: 검색창에 “서울” 키워드를 입력하고, 결과 목록이 뜨도록 자동화
  2. BeautifulSoup: 동적으로 로드된 HTML에서 매장명, 주소, (전화번호) 등을 파싱
  3. pandas: 크롤링한 데이터를 DataFrame에 담아 전처리 및 Excel로 저장
  4. 데이터 병합: 시군구별 매장 수를 계산하고, 인구 데이터(sgg_pop)나 사업체 수(sgg_biz)와 merge
  5. folium:
    • Choropleth 지도: 시군구별 통계(매장 수 등)를 색으로 표현
    • (옵션) CircleMarker: 각 매장 위치 표시 (단, 좌표가 없다면 지오코딩 필요)

3. 메가커피 예시 적용

(1) 사이트 구조 파악

  • 메가커피 사이트는 스타벅스와 달리 위도·경도 속성이 따로 없다
  • <li> 태그 안에 <b>로 된 매장명, <div class="cont_text_inner cont_text_info"> 안에 주소+전화번호가 존재
  • 검색창의 id="store_search"에 “서울”을 입력 → Ajax 로딩 후 결과 <li> 목록이 생성

 

(2) 크롤링 코드 (Selenium + BeautifulSoup)

 

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from bs4 import BeautifulSoup
import pandas as pd
import time

url = "https://www.mega-mgccoffee.com/store/find/"
driver = webdriver.Chrome()
driver.get(url)
time.sleep(3)

search_box = driver.find_element(By.ID, 'store_search')
search_box.send_keys("서울")
search_box.send_keys(Keys.RETURN)
time.sleep(3)

html = driver.page_source
soup = BeautifulSoup(html, 'html.parser')
store_list = soup.select('#store_search_list > li')

mega_list = []
for item in store_list:
    name = item.select('b')[0].text.strip()
    info_str = item.select_one("div.cont_text_inner.cont_text_info").text.strip()
    # 주소+전화번호가 한 줄에 있어 마지막 공백 분리
    split_result = info_str.rsplit(' ', 1)
    address = split_result[0]
    phone   = split_result[1]
    mega_list.append([name, address, phone])

driver.quit()
mega_df = pd.DataFrame(mega_list, columns=["매장명", "주소", "전화번호"])
mega_df.to_excel("seoul_mega_list.xlsx", index=False)

이렇게 하면 매장 정보 엑셀을 얻을 수 있습니다.

(3) 시군구별 매장 수 & 기존 통계 병합

  • 주소에서 시군구명만 뽑아(예: addr.split()[1]), 구 단위로 매장 수 계산
  • 기존에 있는 sgg_pop.xlsx(구별 인구), sgg_biz.xlsx(구별 사업체 수) 등과 merge
sgg_names = [addr.split()[1] for addr in mega_df["주소"]]
mega_df["시군구명"] = sgg_names

mega_sgg_count = mega_df.pivot_table(index="시군구명", values="매장명", aggfunc="count") \
                       .rename(columns={"매장명": "메가커피_매장수"})

seoul_sgg = pd.merge(sgg_pop_df, mega_sgg_count, on="시군구명", how="left")
seoul_sgg = pd.merge(seoul_sgg, sgg_biz_df, on="시군구명", how="left")

seoul_sgg.to_excel("seoul_sgg_mega_stat.xlsx", index=False)

이렇게 하면 인구·사업체 수·메가커피 매장수가 한꺼번에 들어있는 DataFrame을 얻습니다.

(4) 지도 시각화 (Choropleth)

  • 위 스크린샷과 같이, 서울시 행정경계 GeoJSON(seoul_sgg.geojson)을 불러와 각 구의 매장수를 색으로 표시
  • folium.Choropleth의 data 파라미터에 seoul_sgg를 넘겨주고, columns를 [“시군구명”, “메가커피_매장수”]로 지정
import folium, json
geo_path = "seoul_sgg.geojson"
geo_data = json.load(open(geo_path, encoding='utf-8'))

m = folium.Map(location=[37.57305, 126.979189], zoom_start=11)
folium.Choropleth(
    geo_data=geo_data,
    data=seoul_sgg,
    columns=["시군구명","메가커피_매장수"],
    key_on="properties.SIG_KOR_NM",
    fill_color="YlGn"
).add_to(m)

m.save("mega_choropleth.html")
 

생성된 mega_choropleth.html을 열면, 위 사진과 유사한 지도가 보입니다.


4. 주의사항 및 확장

  1. 위도·경도가 없다면?
    • 메가커피는 <li> 태그에 data-lat, data-long 같은 속성이 없으므로 지오코딩(카카오/네이버 등)으로 주소 → 좌표를 얻어야 CircleMarker를 찍을 수 있음.
  2. Ajax 로딩
    • 검색 결과가 늦게 뜰 경우, time.sleep() 외에 명시적 대기(Explicit Wait)를 고려해야 함.
  3. 응용
    • 다른 웹페이지(맛집, 부동산, 리뷰 사이트 등) 구조만 파악하면, 비슷한 방식으로 크롤링 & 병합 가능
    • 수집된 데이터를 머신러닝, 통계 분석, 대시보드 등으로 확장 가능

5. 결론

이번 학습 프로젝트에서는 Selenium + BeautifulSoup + pandas + folium 조합으로,

  1. 동적 웹페이지에서 검색 후 데이터를 자동 수집하고,
  2. 기존 통계와 병합하여 구 단위로 통계를 낸 뒤,
  3. 지도 시각화를 통해 인사이트를 얻는 과정을 거쳤습니다.
  • 메가커피는 그저 ‘주소, 전화번호, 매장명’을 모으기 위한 예시 사이트일 뿐이고,
  • 학습 목적: 어떤 사이트든 이런 식으로 크롤링전처리시각화가 가능하다는 점을 익히는 것.

 

 

결과적으로, 프로젝트 전체 흐름을 반복 연습하면 다른 사이트에서도 HTML 선택자만 조금 바꿔주면 크롤링이 가능하고,
pandas를 통해 **다양한 부가 데이터(인구, 사업체 수, 유동인구...)**와 결합하여 흥미로운 지역 분석을 수행할 수 있게 됩니다.

특히 지도 이미지처럼, Choropleth 시각화를 통해 한눈에 어느 구가 매장이 많고 적은지, 인구 대비 매장이 어느 정도인지 등을 직관적으로 파악할 수 있습니다.

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2026/04   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30
글 보관함