주제
이디야는 정말 스타벅스 근처에 매장을 오픈할까?
Step1. 스타벅스 가져오기
- 메인 페이지 열기
url = 'https://www.starbucks.co.kr/index.do'
driver = webdriver.Chrome('../driver/chromedriver.exe')
driver.get(url)
- 스토어 페이지 열기
driver.maximize_window()
storePage = driver.find_element(By.CSS_SELECTOR, '#gnb > div > nav > div > ul > li.gnb_nav03 > h2 > a')
action = ActionChains(driver)
action.move_to_element(storePage).perform()
time.sleep(1)
driver.find_element(By.CSS_SELECTOR,'#gnb > div > nav > div > ul > li.gnb_nav03 > div > div > div > ul:nth-child(1) > li.gnb_sub_ttl > a').click()
time.sleep(1.5)
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.5)
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.5)
driver.find_element(By.CSS_SELECTOR,'#mCSB_2_container > ul > li:nth-child(1) > a').click()
- 매장정보 가져오기
from bs4 import BeautifulSoup
page = driver.page_source
soup = BeautifulSoup(page,'html.parser')
content = soup.select('#mCSB_3 li.quickResultLstCon')
- 태그선택이 생각보다 어렵다
- 여러개의 리스트 형태로 보여야 하니깐 이점을 잘 기억해두자
starbucksName = []
starbucksLat = []
starbucksLong = []
starbucksAddress = []
starbucksGu = []
for n in range(0, len(content)):
name = content[n].select_one('strong').text.rstrip(' ')+'점'
lat = content[n]['data-lat']
long = content[n]['data-long']
address_split = content[n].find('p').text.split()[:-1]
address = ' '.join(address_split)
gu = address_split[1]
starbucksName.append(name)
starbucksLat.append(lat)
starbucksLong.append(long)
starbucksAddress.append(address)
starbucksGu.append(gu)
starbucks = pd.DataFrame({
'매장명' : starbucksName,
'주소' : starbucksAddress,
'구' : starbucksGu,
'위도' : starbucksLat,
'경도' : starbucksLong
})
guList = starbucks.구.unique().tolist()
guList
data = []
data.append({
'name' : name,
'aderess' : address,
...
})
pd.DataFrame(data)
Step2. 스타벅스 가져오기
- 메인페이지 열기
url = 'https://ediya.com/'
driver = webdriver.Chrome('../driver/chromedriver.exe')
driver.get(url)
- 스토어 페이지 열기
page = driver.page_source
soup = BeautifulSoup(page,'html.parser')
driver.maximize_window()
driver.find_element(By.CSS_SELECTOR, 'body > header > div > div > div.gnb_wrap > div.top_util > ul.top_members > li.store > a').click()
time.sleep(2)
driver.find_element(By.CSS_SELECTOR, '#contentWrap > div.contents > div > div.store_search_pop > ul > li:nth-child(2) > a').click()
time.sleep(2)
keyword = driver.find_element(By.CSS_SELECTOR, '#keyword').click()
time.sleep(2)
def scrapFunction(region,gu=False,*inputGu):
list1 = []
list2 = []
list3 = []
dic = {}
print(inputGu[0])
for item in region:
print(f'현재: {item}')
driver.find_element(By.CSS_SELECTOR, '#keyword').click()
time.sleep(0.5)
driver.find_element(By.CSS_SELECTOR, '#keyword').clear()
driver.find_element(By.CSS_SELECTOR, '#keyword').send_keys(item)
time.sleep(3)
driver.find_element(By.CSS_SELECTOR, '#keyword_div > form > button').click()
time.sleep(2)
result = None
try:
result = driver.switch_to.alert
except:
pass
if result:
result.dismiss()
print(f'데이터 없음 : {item}')
continue
else:
page = driver.page_source
soup = BeautifulSoup(page,'html.parser')
contents = soup.select('#placesList dl')
for content in contents:
name = content.select_one('dt').text
address_split = content.select_one('dd').text.split(' ')
if address_split[0] == '서울':
if address_split[-1] == '':
address_split.remove('')
print(f'remove address_split : {address_split}')
if address_split[-1][-1] == ')':
for idx, value in enumerate(address_split):
if value[0] =='(':
address =' '.join(address_split[:idx])
else:
address = ' '.join(address_split)
print(f'name: {name}')
print(f'ADDRESS : {address}')
list1.append(name)
list2.append(address)
if gu:
list3.append(inputGu[0])
else:
list3.append(item)
else:
continue
time.sleep(3)
dic = {
'매장명' : list1,
'주소' : list2,
'구' : list3
}
return dic
- 첫 번째 : 일단 너무 어렵게 짠거 같다
- 두 번째 : 주소가 바뀌지 않아도 parser를 해주어야 한다
- 세 번째 : 경고창 끄기
- 네 번째 : 서울 붙여주자
- 위키백과 가져오기
import urllib
from urllib.request import urlopen, Request
html = 'https://ko.wikipedia.org/wiki/{search_words}'
req = Request(html.format(search_words=urllib.parse.quote('강서구_(서울특별시)')))
response = urlopen(req)
response.status
soup = BeautifulSoup(response,'html.parser')
print(soup.prettify())
- 한국어 가져오기 위해 format 사용!!!!!!
Step3. 분석하기
- 주소로 위도경도 가져오기
my_key =
gmaps = googlemaps.Client(key=my_key)
for idx , row in tqdm_notebook(ediya.iterrows()):
tmp = gmaps.geocode(row['주소'], language="ko")
print(tmp)
lat = tmp[0].get("geometry")["location"]["lat"]
lng = tmp[0].get("geometry")["location"]["lng"]
ediya.loc[idx,'위도'] = lat
ediya.loc[idx,'경도'] = lng
- 지도에 그리기
m = folium.Map(
location=[37.535855, 126.991558],
zoom_start=11,
tiles='OpenStreetMap'
)
for idx, row in df_sum.iterrows():
color = 'green' if row['브랜드'] == '스타벅스' else 'blue'
folium.CircleMarker(
location = [row['위도'],row['경도']],
radius=3,
fill=False,
color = color
).add_to(m)
- 그래프
plt.figure(figsize=(15,10))
sns.countplot(x='구', hue='브랜드', palette='Set2', data = df_sum)
plt.show()
plt.figure()
plt.barh(df_result.index, df_result['스타벅스 매장당 인구수(비율)'], label='스타벅스')
plt.barh(df_result.index, -df_result['이디야 매장당 인구수(비율)'], label='이디야')
plt.xlabel('구 별 매장당 인구수 비율')
plt.ylabel('구')
plt.xticks([-5,-2.5,0,5,10],(10,5,0,5,10))
plt.show()
- 인구수를 괜히 들고 왔나 싶기도 하다
- groupby 와 pivot table을 자유자재로 사용 할 수 있으면 편할거 같다
- 가설검정
Step4. 마무리
- 다른 자치구에 매장을 오픈하는건 알겠는데 자치구 내에서 어떤가는 모르겠따,,
- 자치구 내에서 가깝게 있는가를 알아보려면 뭐가 필요할까?
- 1. 가깝다는 기준 : 가깝다는 기준이 없다! 이에대한 레퍼런스가 필요할듯? 현업에서도 많이 겪는 문제라고 한다.
- 2. 스타벅스와 이디야 매장 오픈 시기 : 이디야가 근처에 있다면 스타벅스 매장 오픈 시기보다 늦어야 한다. 추가 분석을 한다면 꼭 필요하다
- 3. 거리문제 : harvsin을 사용하여 직선거리를 구했지만 실제 도로상황을 고려해야한다. 이것을 어떤 변수로? 혹은 실제 지도 앱에서 찍히는 거리를 가져오거나? 해야하나? 이건 모르겠네.. 이것도 레퍼런스가 필요한것 같다
- 코트는 조금 더러운거 같은데 어떻게 하면 데이터를 기반으로 근거를 제시하면 좋을지 생각해봤다는 점에서 의의를 둔다