[강의 요약]
[Part 04. EDA/웹 크롤링/파이썬 프로그래밍_ Ch 04. 웹 데이터 분석] 강의 수강
클립 14~20까지 강의 수강하였음
20_실습 - 시카고 맛집 데이터 지도 시각화까지
🐢 100일 챌린지 🔥 : [▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰ ] 60/100일 (60%)
60일!
[클립 14~20까지 정리]
▶ 시카고 맛집 데이터 분석_개요
목표 : 시카고 매거진에 소개된 50개 샌드위치 맛집 정보를 모두 가져오는 것
추출할 정보 : 가게 이름, 대표 메뉴, 가격, 주소
출처 : https://www.chicagomag.com/Chicago-Magazine/November-2012/Best-Sandwiches-Chicago/
페이지 구성
- 메인 페이지 : 50개 맛집의 메뉴명, 가게명, 세부페이지 링크 제공
- 세부 페이지 : 각 가게의 주소, 전화번호, 가격 등 상세 정보 제공
▶ 1. 메인 페이지 크롤링
접근 태그 확인
<div class="sammy">
<h2>1. BLT</h2>
<div><a href="...">Old Oak Tap</a></div>
</div>
BeautifulSoup 코드 예시
from urllib.request import urlopen
from bs4 import BeautifulSoup
import pandas as pd
import re
url = 'https://www.chicagomag.com/.../Best-Sandwiches-Chicago/'
html = urlopen(url)
soup = BeautifulSoup(html, 'html.parser')
sammies = soup.find_all('div', 'sammy')
데이터 추출(랭킹, 메뉴, 가게이름, URL)
list_rank = []
list_menu = []
list_cafe = []
list_url = []
for item in sammies:
list_rank.append(item.find('div', 'sammyRank').text)
tmp = item.find('div', 'sammyListing').text
menu, cafe = re.split(r'\n|\r', tmp.strip())[:2]
list_menu.append(menu.strip())
list_cafe.append(cafe.strip())
list_url.append(item.find('a')['href'])
*re.split()을 사용하면 메뉴와 가게를 쉽게 분리할 수 있다.
▶ 2. DataFrame 만들기 및 저장
df = pd.DataFrame({
'Rank': list_rank,
'Menu': list_menu,
'Cafe': list_cafe,
'URL': list_url
})
df.to_csv("chicago_sandwiches.csv", index=False)
▶ 3. 하위 페이지(가게 개별 링크) 정보 추출
각 URL에 접근해서 가격과 주소 추출
from tqdm import tqdm
price_list = []
addr_list = []
for link in tqdm(df['URL']):
html_sub = urlopen(link)
soup_sub = BeautifulSoup(html_sub, 'html.parser')
p_tag = soup_sub.find('p', class_='addy').text.strip()
price = re.search(r'\$(\d+\.?\d*)', p_tag).group(1)
address = re.sub(r'\$\d+\.?\d*', '', p_tag).strip()
price_list.append(price)
addr_list.append(address)
re.search()로 가격을 찾고, re.sub()로 그 부분을 제거해 주소만 남긴다.
▶ 4. 전체 통합 및 저장
df['Price'] = price_list
df['Address'] = addr_list
# 순서 정리
cols = ['Rank', 'Cafe', 'Menu', 'Price', 'Address', 'URL']
df = df[cols]
# 저장
df.to_csv("chicago_sandwich_final.csv", index=False)
▶ 5. Folium으로 지도 시각화
지도 준비
import folium
from geopy.geocoders import Nominatim
g = Nominatim(user_agent='geoapi')
위도/경도 정보 추가
lat_list = []
lng_list = []
for addr in tqdm(df['Address']):
location = g.geocode(addr + ', Chicago')
lat_list.append(location.latitude)
lng_list.append(location.longitude)
지도에 원형 마커 표시
m = folium.Map(location=[41.8781, -87.6298], zoom_start=11)
for i in df.index:
folium.CircleMarker(
[lat_list[i], lng_list[i]],
radius=5,
popup=df.loc[i, 'Cafe'],
color='blue', fill=True
).add_to(m)
m.save("chicago_map.html")
[Folium 이란?]
Folium은 Python에서 지도를 시각화할 수 있게 해주는 라이브러리
우리가 수집한 데이터가 어느 위치에 있는지 지도 위에 (잘)보여주는 역할을 한다.
- 웹 기반 지도 (Leaflet.js)를 파이썬으로 쉽게 다룰 수 있다.
- 지도는 .html 파일로 저장되어 웹브라우저에서 열 수 있다.
▶ Folium의 기본 구조
import folium
# 지도 객체 만들기
m = folium.Map(location=[위도, 경도], zoom_start=11)
# 마커 추가하기
folium.Marker([위도, 경도], popup='설명').add_to(m)
# 저장하기
m.save('map.html')
- folium.Map() : 지도의 시작 위치와 확대 수준 설정
- Marker() : 해당 위치에 점을 찍음 (클릭하면 설명이 뜬다)
- save() : HTML로 저장해서 브라우저에서 볼 수 있게 함
▶ 원형 마커(CircleMarker) 사용은 어떻게?
folium.CircleMarker(
location=[위도, 경도],
radius=5, # 원 크기
color='blue', # 테두리 색
fill=True,
fill_color='blue',
popup='장소 이름'
).add_to(m)
- radius : 원의 반지름 (숫자가 클수록 큼)
- popup : 클릭 시 뜨는 말풍선 설명
- color, fill_color : 테두리/채우기 색상
CircleMarker는 숫자 기반 값을 시각화할 때 유용함 (ex: 사고 건수, 인구 등)
▶ 실제 데이터에 적용하는 순서
1. 주소 → 위도/경도 변환
from geopy.geocoders import Nominatim
g = Nominatim(user_agent='geoapi')
location = g.geocode('서울특별시 강남구')
print(location.latitude, location.longitude)
2. 지도 만들고 마커 추가
m = folium.Map(location=[location.latitude, location.longitude], zoom_start=12)
folium.Marker([location.latitude, location.longitude], popup='강남구').add_to(m)
m.save('map.html')
[나의 생각 정리]
Folium 라이브러리를 사용하는 방법을 알 수 있었다.
기대 이상으로 유용한 라이브러리인 것 같은데, 프로젝트에서 사용해 봐야 알듯하다.
[적용점]
데이터 분석(EDA)에서 사용
“이 글은 제로베이스 데이터 스쿨 주 3일반 강의 자료 일부를 발췌하여 작성되었습니다.”
'제로베이스 데이터 취업 파트타임 > 100일 챌린지_일일 학습 일지' 카테고리의 다른 글
제로베이스 데이터 파트타임 스쿨 학습 일지 [25.05.17] (0) | 2025.05.17 |
---|---|
제로베이스 데이터 파트타임 스쿨 학습 일지 [25.05.16] (3) | 2025.05.16 |
제로베이스 데이터 파트타임 스쿨 학습 일지 [25.05.14] (0) | 2025.05.14 |
제로베이스 데이터 파트타임 스쿨 학습 일지 [25.05.13] (0) | 2025.05.13 |
제로베이스 데이터 파트타임 스쿨 학습 일지 [25.05.12] (2) | 2025.05.12 |