필요 모듈 호출
import time
import pandas as pd
import numpy as np
from selenium import webdriver
from selenium.webdriver.common.by import By
from bs4 import BeautifulSoup
from tqdm import tqdm_notebook
from selenium import webdriver
#스타벅스 페이지 접근
url='https://www.starbucks.co.kr/store/store_map.do?disp=locale'
driver=webdriver.Chrome()
driver.get(url)

search_area = driver.find_element(By.CSS_SELECTOR, '#container > div > form > fieldset > div > section > article.find_store_cont > article > header.loca_search > h3 > a')
search_area.click()

choose_area = driver.find_element(By.CSS_SELECTOR, '#container > div > form > fieldset > div > section > article.find_store_cont > article > article:nth-child(4) > div.loca_step1 > div.loca_step1_cont > ul > li:nth-child(1) > a')
choose_area.click()
all_gu = driver.find_element(By.CSS_SELECTOR, '#mCSB_2_container > ul > li:nth-child(1) > a')
all_gu.click()
html = driver.page_source
soup = BeautifulSoup(html, 'html.parser')
store_list_raw = soup.select_one('ul.quickSearchResultBoxSidoGugun')
store_list = store_list_raw.select('li.quickResultLstCon')
확인
store_list[0].text

split 하기에 불편하니, 태그로 접근
store_list[123].select_one('p').text

store_list[123].select_one('p').text[:-9]

store_list[123].select_one('strong').text

store_list[123].select_one('strong').text[:-2]

store_list[123].select_one('p').text.split()[1]

정보 긁어오기
address_list = [] # 주소
name_list = [] # 이름
gu_list = [] # 구
lat = []
lng = []
for i in range(len(store_list)):
name_list.append(store_list[i].select_one('strong').text[:-2])
address_list.append(store_list[i].select_one('p').text[:-9])
gu_list.append(store_list[i].select_one('p').text.split()[1])
lat.append(store_list[i]['data-lat'])
lng.append(store_list[i]['data-long'])
데이터 프레임
starbucks = pd.DataFrame(
{
'매장명':name_list,
'주소':address_list,
'구':gu_list,
'브랜드':'스타벅스',
'위도':lat,
'경도':lng
}
)

켜져있는 셀레니움 종료
driver.quit()
#이디야 페이지 접근
url='https://www.ediya.com/contents/find_store.html'
driver=webdriver.Chrome()
driver.get(url)
#구 목록 만들기
gu_array = starbucks['구'].unique()
gu_array

주소 버튼 클릭
address_button = driver.find_element(By.CSS_SELECTOR, '#contentWrap > div.contents > div > div.store_search_pop > ul > li:nth-child(2) > a')
address_button.click()
검색 창, 검색 버튼 접근
search_bar = driver.find_element(By.CSS_SELECTOR, '#keyword')
search_button = driver.find_element(By.CSS_SELECTOR, '#keyword_div > form > button')
name_list = []
address_list = []
gu_list = []
for gu in tqdm_notebook(gu_array):
#구 검색
search_bar.send_keys(f'서울 {gu}')
time.sleep(1)
search_button.click()
time.sleep(1)
#BeautifulSoup사용 해 html 가져오기
html = driver.page_source
soup = BeautifulSoup(html, 'html.parser')
#매장 정보에 접근
place_list_raw = soup.select_one('ul#placesList')
place_list = place_list_raw.select('.item')
for place in place_list:
#데이터 긁어오기
name = place.select_one('dt').text
address = place.select_one('dd').text
name_list.append(name)
address_list.append(address)
gu_list.append(gu)
#검색창 초기화
search_bar.clear()
ediya = pd.DataFrame(
{
'매장명':name_list,
'주소':address_list,
'구':gu_list,
'브랜드':'이디야',
'위도':np.nan,
'경도':np.nan
}
)

count=0
for idx, row in ediya.iterrows():
a = row['주소'].split()[:4]
if len(a) == 3:
count += 1
print(idx, row['매장명'], a)
print(count)

changeDict = {
0:'서울 강남구 봉은사로37길 29',
13:'서울 강남구 언주로148길 14',
25:'서울 강남구 논현로167길 16',
146:'서울 광진구 강변역로4길 34',
175:'서울 금천구 시흥대로 198',
202:'서울 노원구 월계로45길 37',
293:'서울 서대문구 통일로 203-1',
297:'서울 서대문구 통일로 369',
300:'서울 서대문구 통일로 141',
310:'서울 서대문구 통일로 431',
316:'서울 서초구 효령로60길 15',
322:'서울 서초구 효령로40길 4',
324:'서울 서초구 서초중앙로 89',
326:'서울 서초구 반포대로21길 23',
337:'서울 서초구 청계산로 189',
506:'서울 종로구 삼일대로 436-1',
515:'서울 종로구 홍지문2길 6',
524:'서울 종로구 삼봉로 81',
531:'서울 종로구 수표로 109-1'
}
키 값을호 해당 index로 잡고 바꿔줄 주소를 값으로 하는 공간 생성
for key in changeDict.keys():
ediya['주소'][key] = changeDict[key]
다시 확인
count=0
for idx, row in ediya.iterrows():
a = row['주소'].split()[:4]
if len(a) == 3:
count += 1
print(idx, row['매장명'], a)
print(count)

진짜 위도 경도 추가
import googlemaps
import folium
import pandas as pd
import json
from tqdm import tqdm_notebook
gmaps_key = '할당받은 개인 키'
gmaps = googlemaps.Client(key=gmaps_key)
# 위도, 경도 채우기
for idx, row in tqdm_notebook(ediya.iterrows()):
address = row['주소'].split()[:4]
print(' '.join(address))
tmp = gmaps.geocode(' '.join(address), language='ko')
lat = tmp[0]['geometry']['location']['lat']
lng = tmp[0]['geometry']['location']['lng']
ediya['위도'][idx], ediya['경도'][idx] = lat, lng
확인

-folium 사용하여 지도에 표시
import json
import folium
import warnings
warnings.simplefilter(action='ignore', category='FutureWarning')
geo_path = './skorea_municipalities_geo_simple.json'
geo_str = json.load(open(geo_path, encoding='utf-8'))
my_map = folium.Map(location=[37.5502, 126.982], zoom_start=12, tiles='CartoDB positron')
for idx, rows in ediyaAdded.iterrows():
latitude = rows['위도']
longitude = rows['경도']
if latitude is not None and longitude is not None:
folium.CircleMarker(
location=[rows['위도'], rows['경도']],
radius=1,
color='lightblue'
).add_to(my_map)
my_map

my_map_2 = folium.Map(location=[37.5502, 126.982], zoom_start=12, tiles='CartoDB positron')
for idx, rows in df_added.iterrows():
latitude = rows['위도']
longitude = rows['경도']
if latitude is not None and longitude is not None:
folium.CircleMarker(
location=[rows['위도'], rows['경도']],
radius=1,
color='green'
).add_to(my_map_2)
my_map_2

my_map_3 = folium.Map(location=[37.5502, 126.982], zoom_start=12, tiles='CartoDB positron')
# 이디야
for idx, rows in ediyaAdded.iterrows():
latitude = rows['위도']
longitude = rows['경도']
if latitude is not None and longitude is not None:
folium.CircleMarker(
location=[rows['위도'], rows['경도']],
radius=1,
color='red',
legend_name='이디야'
).add_to(my_map_3)
# 스타벅스
for idx, rows in df_added.iterrows():
latitude = rows['위도']
longitude = rows['경도']
if latitude is not None and longitude is not None:
folium.CircleMarker(
location=[rows['위도'], rows['경도']],
radius=1,
color='green',
legend_name='스타벅스'
).add_to(my_map_3)
my_map_3

해석
문제 : 이디야는 스타벅스 옆에 매장을 만드는가?