로딩 중이에요... 🐣
[코담]
웹개발·실전 프로젝트·AI까지, 파이썬·장고의 모든것을 담아낸 강의와 개발 노트
03 요약정리 | ✅ 저자: 이유정(박사)
Selenium과 BeautifulSoup을 활용한 카카오맵 크롤링 정리
카카오맵에서 특정 지역(예: "강남구 카페")을 검색하고, 여러 페이지에 걸쳐 가게 이름, 평점, 주소, 영업시간 등의 정보를 자동으로 수집하는 크롤링 자동화 과정을 정리합니다.
1. 설치 준비
필수 패키지 설치
pip install selenium
pip install webdriver-manager
pip install beautifulsoup4
pip install pandas
2. 폴더 구조 예시
프로젝트 루트/
│
├── selenium_crawler/
│ └── kakaomap_scrap.py
│
└── kakaomap.ipynb ← Jupyter Notebook 파일
selenium_crawler 디렉토리 만들고, kakaomap_scrap.py 생성 후 아래 크로릴코드를 넣는다.
그리고, kakaomap.ipynb 파일 생성후 실행하면 나머지 파일들은 자동으로 생성된다.
3. 크롤링 코드 (kakaomap_scrap.py
)
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as ec
from bs4 import BeautifulSoup
from time import sleep
def get_items(html, parsed_items):
soup = BeautifulSoup(html, "html.parser")
items = soup.select("li.PlaceItem.clickArea")
for item in items:
item_dict = {}
item_dict["name"] = item.find("span", {"data-id": "screenOutName"}).text
item_dict["score"] = item.find("em", {"data-id": "scoreNum"}).text
item_dict["address"] = item.find("p", {"data-id": "address"}).text
item_dict["hour"] = item.find("a", {"data-id": "periodTxt"}).text
parsed_items.append(item_dict)
return parsed_items
def get_data_from_kakaomap():
try:
from selenium.webdriver.chrome.options import Options
options = Options()
options.add_argument("--headless=new")
options.add_argument("--disable-gpu")
options.add_argument("--no-sandbox")
service = Service(ChromeDriverManager().install())
driver = webdriver.Chrome(service=service, options=options)
driver.set_page_load_timeout(30)
driver.get("https://map.kakao.com/")
wait = WebDriverWait(driver, 10)
wait.until(ec.visibility_of_element_located((By.ID, "search.keyword.query")))
search_input = driver.find_element(By.ID, "search.keyword.query")
search_input.send_keys("강남구 카페")
search_input.send_keys(Keys.ENTER)
wait.until(ec.element_to_be_clickable((By.ID, "info.search.place.more")))
driver.execute_script("""
var element = document.getElementById('dimmedLayer');
if (element) {
element.className = 'DimmedLayer HIDDEN';
}
""")
sleep(1)
show_more_btn = driver.find_element(By.ID, "info.search.place.more")
show_more_btn.click()
wait.until(ec.visibility_of_element_located((By.ID, "info.search.page")))
page_count = 0
items = []
while page_count <= 5:
if page_count != 0 and page_count % 5 == 0:
next_btn = driver.find_element(By.ID, "info.search.page.next")
next_btn.click()
wait.until(ec.visibility_of_element_located((By.ID, "info.search.place.list")))
page_count += 1
page_num = page_count % 5 if page_count % 5 != 0 else 5
page_btn = driver.find_element(By.ID, f"info.search.page.no{page_num}")
page_btn.click()
wait.until(ec.visibility_of_element_located((By.ID, "info.search.place.list")))
place_list = driver.find_element(By.ID, "info.search.place.list")
shop_list = place_list.get_attribute("innerHTML")
get_items(shop_list, items)
sleep(2)
driver.quit()
return items
except Exception as e:
print("에러 발생:", e)
raise e
4. Jupyter Notebook에서 실행 (kakaomap.ipynb
)
import sys, os
sys.path.append(os.getcwd())
from selenium_crawler.kakaomap_scrap import get_data_from_kakaomap as get_data_v2
# 데이터 수집 실행
data = get_data_v2()
data[:3] # 앞에서 3개 미리 보기
5. 크롤링 흐름 요약
단계 | 설명 |
---|---|
1 | 웹드라이버 셋업 및 크롬 브라우저 실행 |
2 | 카카오맵 열고 검색창에 검색어 입력 (ex. 강남구 카페) |
3 | 더보기 버튼 클릭하여 페이지 버튼 노출 |
4 | 1~6페이지 반복 클릭하며 결과 수집 |
5 | HTML 수집 후 BeautifulSoup으로 파싱 |
6 | 가게 이름, 평점, 주소, 영업시간 정보 저장 |
6. 결과 예시
{'name': '별다방', 'score': '4.3', 'address': '서울 강남구 테헤란로...', 'hour': '09:00 ~ 22:00'}
7. Pandas로 정리 및 CSV 파일 저장
pip install pandas
import pandas as pd
# 리스트를 DataFrame으로 변환
df = pd.DataFrame(data)
# 컬럼 순서 재정렬 (선택사항)
df = df[['name', 'score', 'address', 'hour']]
# CSV로 저장
df.to_csv("강남구_카페_목록.csv", index=False, encoding='utf-8-sig')
CSV 파일은 Excel에서도 바로 열 수 있으며, utf-8-sig
인코딩으로 저장하면 한글이 깨지지 않습니다.
8. VS Code에서 Jupyter 실행 방법
- VS Code 좌측 확장(Extensions)에서 Jupyter 확장 설치
.ipynb
파일을 열면 상단에 실행 버튼이 생김- 커널 선택 후 셀별로 실행 (
Shift + Enter
) - Python 가상환경을 연결하려면 좌측 하단 Python 인터프리터 클릭하여
venv
선택
9.오류 해결 팁: TimeoutError 발생 시
원인
- Selenium이 내부적으로 사용하는
localhost:포트
접속에 실패한 경우 (크롬 실행 실패) driver.get()
에서 카카오맵 페이지 로딩 중 타임아웃 발생
해결 방법
- headless 옵션 추가: 백그라운드 실행 시 에러 방지
- 명시적 타임아웃 설정:
driver.set_page_load_timeout(30)
- 크롬 드라이버 호환성 확인:
chromedriver_autoinstaller
활용 가능
pip install chromedriver-autoinstaller
import chromedriver_autoinstaller
chromedriver_autoinstaller.install()
driver = webdriver.Chrome()
10. jupyter 브라우저 실행시
jupyter notebook --no-browser --port 8888
비밀번호 재설정하기 (초기화)
jupyter notebook password
참고 링크
- Selenium WebDriver 공식 문서: https://www.selenium.dev/documentation/webdriver/
- Webdriver-Manager: https://pypi.org/project/webdriver-manager/
- 카카오맵: https://map.kakao.com/