import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
from matplotlib import font_manager, rc
plt.rcParams['font.family'] = 'Malgun Gothic'
from selenium import webdriver
import requests
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import re
from urllib.request import urlopen
from tqdm import tqdm_notebook
import folium
import platform
import time
import tqdm
driver = webdriver.Chrome('driver/chromedriver.exe') # 구글드라이버 경로 입력
driver.get("https://www.starbucks.co.kr/store/store_map.do ") # 원하는 창 오픈
driver.maximize_window() # 화면 최대화
driver.find_element(By.CSS_SELECTOR, "#container > div > form > fieldset > div > section > article.find_store_cont > article > header.loca_search > h3 > a").click() # 지역검색 클릭
time.sleep(1)
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").click() # 서울 클릭
time.sleep(1)
driver.find_element(By.CSS_SELECTOR, '#mCSB_2_container > ul > li:nth-child(1) > a').click() # 전체 클릭
time.sleep(3)B
from bs4 import BeautifulSoup
req = driver.page_source # 해당 페이지 저장
soup = BeautifulSoup(req, 'html.parser')
print(soup.prettify())
contents = soup.select('.quickResultLstCon') # 매장별 정보
contents
contents[30].select_one('p').text # 주소 정보 확인
Output : '서울특별시 강남구 삼성로 402 (대치동)1522-3232’
contents[30].select_one('strong').text # 지점 확인
Output : '대치사거리 ‘
contents[30].select_one('p').text.split(' ')[1] # 구 정보 확인
Output : '강남구’
이름
, 주소
, 구
이름에 해당하는 데이터 리스트 생성# 데이터 프레임 만들기
name_list = []
gu_name_list = []
address_list = []
for data in tqdm_notebook(contents):
name = data.select_one("strong").text[:-2] # 이름
address = data.select_one("p").text # 주소
gu_name = data.select_one("p").text.split(" ")[1] # 구 이름
name_list.append(name)
address_list.append(address)
gu_name_list.append(gu_name)
time.sleep(0.5)
driver.quit()
df = pd.DataFrame(
{'name':name_list,
'address':address_list,
'gu_name': gu_name_list})
df
df.iloc[0:4]
df.drop([0, 1, 2, 3], axis = 0, inplace = True) # 부산지역 4개 가 같이 따라와서 삭제
df.reset_index(drop = True)
데이터 저장 (스타벅스)
df.to_csv('starbucks_store.csv', encoding = 'utf-8', index = False) # 데이터 저장
E_driver = webdriver.Chrome('driver/chromedriver.exe') # 구글드라이버 경로 입력
E_driver.get("https://ediya.com/contents/find_store.html ") # 원하는 창 오픈
E_driver.maximize_window() # 화면 최대화
gu_List = df['gu_name'].unique() # 스타벅스 매장 위치 있는 '구' 호출
gu_List
E_driver.find_element(By.CSS_SELECTOR, '#contentWrap > div.contents > div > div.store_search_pop > ul > li:nth-child(2) > a').click() # 주소란에 구를 입력
E_driver.find_element(By.CSS_SELECTOR, '#keyword').send_keys(gu_List[0])
E_driver.find_element(By.CSS_SELECTOR ,'#keyword_div > form > button').click() # 돋보기를 클릭함
E_req = E_driver.page_source # 현재 창 주소 저장
E_soup = BeautifulSoup(E_req, "html.parser")
print(E_soup.prettify())
E_contents = E_soup.select('.item') # 매장별 정보 추출하기 위한 부모 태그
E_contents[2]
Output :
<li class="item"><a href="#c"><div class="store_thum"><img src="../images/customer/store_thum.gif"/></div><dl><dt>강남논현학동점</dt> <dd>서울 강남구 논현로131길 28 (논현동)</dd></dl></a></li>
E_contents[2].select_one('dd').text.split(' ')[1] # 구 이름
Output : '강남구’
E_contents[2].select_one('dt').text # 매장이름
Output : '강남논현학동점’
E_contents[2].select_one('dd').text # 주소
Output : '서울 강남구 논현로131길 28 (논현동)’
E_driver.find_element_by_css_selector("#keyword").clear() # 검색창 지우기
gu_List[-7] = '서울 중구'
gu_List
E_data = []
for guIdx in tqdm_notebook(range(len(gu_List))):
E_driver.find_element(By.CSS_SELECTOR, '#contentWrap > div.contents > div > div.store_search_pop > ul > li:nth-child(2) > a').click() # 주소란에 구를 입력
E_driver.find_element(By.CSS_SELECTOR, '#keyword').send_keys(gu_List[guIdx])
E_driver.find_element(By.CSS_SELECTOR ,'#keyword_div > form > button').click() # 돋보기를 클릭함
time.sleep(0.5)
print(gu_List[guIdx]) # 오류가 발생, 검색정보가 많은 구 확인
E_req = E_driver.page_source # 현재 창 주소 저장
E_soup = BeautifulSoup(E_req, "html.parser")
time.sleep(0.5)
E_contents = E_soup.select('.item') # 매장별 정보 추출하기 위한 부모 태그
time.sleep(0.5)
for data in E_contents:
name = data.select_one('dd').text.split(' ')[1] # 구 이름
address = data.select_one('dt').text # 매장이름
gu = data.select_one('dd').text # 주소
E_data.append({
"이름" : name,
"주소" : address,
"구" : gu
})
E_driver.find_element_by_css_selector("#keyword").clear() # 검색창 지우기
time.sleep(0.5)
driver.quit()
데이터 프레임 생성 및 저장
ediya = pd.DataFrame(E_data) # 데이터프레임 만들어 저장
ediya.to_csv('ediya_store.csv', encoding = 'utf-8', index = False)
df_starbucks = pd.read_csv('starbucks_store.csv', encoding = 'utf-8')
df_ediya = pd.read_csv('ediya_store.csv', encoding = 'utf-8')
brand
column 추가# brand 추가
df_starbucks['브랜드'] = '스타벅스' ; df_ediya['브랜드'] = '이디야'
df_starbucks.columns = ['이름', '주소', '구', '브랜드'] # 두 데이터 프레임 column명 일치
df_ediya.columns = ['구', '이름', '주소', '브랜드'] # 두 데이터 프레임 column명 일치
df_brand = pd.concat([df_starbucks, df_ediya]) # 데이터 병합
df_brand
brandCnt = df_brand[['구','브랜드']].groupby(['브랜드']).count()
brandCnt = brandCnt.reset_index()
brandCnt
brandCnt = df_brand[['구','브랜드']].groupby(['구']).count()
brandCnt.columns = ['매장갯수']
brandCnt = brandCnt.reset_index()
brandCnt = brandCnt.sort_values(by = '매장갯수', ascending = False)
plt.figure(figsize=(20, 6))
fig_1 = sns.barplot(x = '구', y = '매장갯수', data = brandCnt)
plt.title('서울시 구별 총 매장 갯수', size = 18)
sns.despine(offset = 0.5)
for p in fig_1.patches:
cntVal = int(p.get_height())
fig_1.text(
x = p.get_x() + p.get_width() / 2,
y = p.get_height() + p.get_y() + 1,
s = cntVal,
ha = 'center'
)
brandCnt2 = df_brand[['구','브랜드','주소']].groupby(['구','브랜드']).count()
brandCnt2.columns = ['매장갯수']
brandCnt2 = brandCnt2.sort_values(by = '매장갯수', ascending = False)
brandCnt2 = brandCnt2.reset_index()
plt.figure(figsize=(20, 6))
fig_2 = sns.barplot(x = '구', y = '매장갯수', hue = '브랜드', data = brandCnt2, palette= 'Set1')
plt.title('서울시 구별 각 브랜드 매장 갯수', size = 18)
sns.despine(offset = 0.5)
for p in fig_2.patches:
cntVal = int(p.get_height())
fig_2.text(
x = p.get_x() + p.get_width() / 2,
y = p.get_height() + p.get_y() + 1,
s = cntVal,
ha = 'center',
)
# print(f'x = {p.get_x()}, y={p.get_y()} wide={p.get_width()} height={p.get_height()} ')
import googlemaps
gmaps_key = '***********************' # Google Key
gmaps = googlemaps.Client(key = gmaps_key)
gmaps.geocode('이디야 서울 강남YMCA점', language='ko')[0].get('geometry') # Test
tmp1 = df_brand[df_brand['브랜드']=='스타벅스']
tmp2 = df_brand[df_brand['브랜드']=='이디야']
## 좌표 불러오기
tmp1['lat'] = np.nan ; tmp1['lon'] = np.nan
tmp2['lat'] = np.nan ; tmp2['lon'] = np.nan
import googlemaps
gmaps_key = 'AIzaSyAyS0HZsy46gyFUhDlIwYQbHdXXCWHNpc8' # 키 복사 후 입력
gmaps = googlemaps.Client(key = gmaps_key)
for idx, rows in tmp1.iterrows():
try:
staion_name = str(rows['브랜드']) + " " + "서울" + " " + str(rows["이름"])
geo_location = gmaps.geocode(staion_name)[0].get('geometry')
lat = geo_location['location']['lat']
lon = geo_location['location']['lng']
tmp1.loc[idx, 'lat'] = lat
tmp1.loc[idx, 'lon'] = lon
except:
print(f'{idx} address not find')
continue
for idx, rows in tmp2.iterrows():
try:
staion_name = str(rows['브랜드']) + " " + "서울" + " " + str(rows["이름"])
geo_location = gmaps.geocode(staion_name)[0].get('geometry')
lat = geo_location['location']['lat']
lon = geo_location['location']['lng']
tmp2.loc[idx, 'lat'] = lat
tmp2.loc[idx, 'lon'] = lon
except:
print(f'{idx} address not find')
continue
tmpMerge = pd.concat([tmp1, tmp2]) # 데이터 병합
tmpMerge = tmpMerge.dropna()
myMap = folium.Map(
location=[37.541, 126.986], #서울시 좌표
zoom_start = 15,
tiles = 'CartoDB positron')
for idx, rows in tmpMerge.iterrows():
if rows['브랜드'] == '스타벅스':
circle = folium.CircleMarker(
location = [rows['lat'], rows['lon']],
radius = 10,
fill = True,
color = 'red',
fill_color = 'red',
tooltip = rows['이름']
).add_to(myMap)
elif rows['브랜드'] == '이디야':
circle = folium.CircleMarker(
location = [rows['lat'], rows['lon']],
radius = 10,
fill = True,
color = 'blue',
fill_color = 'blue',
tooltip = rows['이름']
).add_to(myMap)
myMap