이전 글에서는 맥도날드의 웹페이지를

크롤링을 통해 가져오고

지점명과 주소 데이터를 담은 테이블을 만들었다.

다음으로 롯데리아, 버거킹 등의 페이지를 BeautifulSoup으로

웹소스를 받아오려 했으나, 구조상의 문제인지

막아놓은 것인지 접근이 잘 안됐다.

그래서 selenium 이라는 웹 테스트 프레임워크를 이용해

크롤링을 진행해봤다.

import sys
if 'google.colab' in sys.modules:
    !apt-get update
    !apt install chromium-chromedriver
    !cp /usr/lib/chromium-browser/chromedriver /usr/bin
    !pip install selenium
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.keys import Keys
options = webdriver.ChromeOptions()
options.add_argument('--headless')
options.add_argument('--no-sandbox')
options.add_argument('--disable-dev-shm-usage')

먼저, 이번 프로젝트는 구글 colab을 통해 진행되기 때문에

colab에서 selenium을 설치하고

webdriver를 불러왔다.

#카카오맵에서 버거킹 검색 후 크롤링을 위한 세팅

driver = webdriver.Chrome('chromedriver',options=options) #웹 드라이버를 크롬으로 실행
driver.implicitly_wait(3) #페이지 로딩을 위해 3초대기

driver.get('https://map.kakao.com/') #크롬드라이버로 카카오맵 접속
driver.find_element_by_xpath('/html/body/div[2]/div/div/form/fieldset/div[1]/input').clear()
#검색창 초기화
driver.find_element_by_xpath('/html/body/div[2]/div/div/form/fieldset/div[1]/input').send_keys('버거킹')
#검색창에 버거킹 입력
driver.find_element_by_xpath('/html/body/div[2]/div/div/form/fieldset/div[1]/input').send_keys(Keys.ENTER)
#엔터를 통해 검색(click이 안됨)

제일 먼저 버거킹을 검색해봤다.

하지만, 검색을 하면 다음과 같이 장소 더보기를 클릭해야한다.

driver.execute_script("document.body.style.zoom='80%'")#자바스크립트를 이용해 웹 사이즈 80%로 줄이기
time.sleep(5) # 5초 대기
driver.execute_script("window.scrollTo(0, 100)") #스크롤을 해서 제일 아래로 내리기
element = driver.find_element_by_id('info.search.place.more') #장소 더보기 찾음
driver.execute_script("arguments[0].click();", element) #장소 더보기 클릭
time.sleep(3) #3초 대기

그렇기 때문에 스크롤을 내리고

장소 더보기를 클릭하는 코드를 추가한다.

 

이렇게 최종적으로 webdriver를 통해 크롬으로 카카오 맵에 접근했다.

카카오 맵에서 버거킹을 검색하면,

406개의 검색 결과가 나오는데, 이는 버거킹 홈페이지에서

확인되는 버거킹 매장의 수와 일치한다.

#카카오맵 페이지 한개 검색 후 데이터 정리
def kMap_one_page():
    html = driver.page_source
    soup = bs(html)
    RETURN_ARR = []

    for tag in soup.findAll('li', attrs={'class': 'PlaceItem'}):
        storeName = tag.findAll('a', attrs={'data-id': 'name'})[0].contents[-1]
        storeAddress = tag.findAll('p', attrs={'data-id': 'address'})[0].contents[-1]
        storeAddress = storeAddress.split()[:2]
        RETURN_ARR.append([storeName] + storeAddress)

    for i in range(len(RETURN_ARR)):
        if regionDic.get(RETURN_ARR[i][1]) == None:
            pass
        else:
            RETURN_ARR[i][1] = regionDic.get(RETURN_ARR[i][1])

    return pd.DataFrame(RETURN_ARR, columns=('store', 'addr1', 'addr2')) if RETURN_ARR else None

카카오맵의 페이지 한개에서

주소 정보를 가져오는 코드이다.

kMap_one_page()

확인을 해보면, 잘 출력되는 것을 볼 수 있다.

def kMap_all_page(lastPage):
    FINAL_RETURN = []
    for n in range(lastPage):
        
        pgNum = (n+1)%5
        print("{}페이지 진행중".format(n+1))
        
        if pgNum != 0:
            pgNum = pgNum 
        elif pgNum == 0:
            pgNum = 5
        
        driver.execute_script("window.scrollTo(0, 100)") #스크롤을 해서 제일 아래로 내리기
        nextPage = "info.search.page.no{}".format(pgNum)
        elem=driver.find_element_by_id(nextPage)
        driver.execute_script("arguments[0].click();", elem)
        time.sleep(3)
        FINAL_RETURN.append(kMap_one_page())
        if (pgNum % 5 == 0):
            driver.execute_script("window.scrollTo(0, 100)") #스크롤을 해서 제일 아래로 내리기
            elem=driver.find_element_by_id("info.search.page.next")
            driver.execute_script("arguments[0].click();", elem)
            time.sleep(3)
        else:
            pass
            
    print("크롤링이 완료됐습니다.")
    driver.quit()
    return pd.concat(FINAL_RETURN)

한페이지에서 검색하는 방식을 활용해

여러 페이지에 적용을 해봤다.

bgk_table = kMap_all_page(27)
display(bgk_table['store'].duplicated())

그리고 중복검사를 해봤으나,

다행히 중복되는 부분은 없었다.

bgk_table

실행을 해보니 출력이 아주 잘 된다.

BGK = bgk_table.apply(lambda x: x['addr1'] + ' ' + x['addr2'], axis=1).value_counts()
BGK.head()

순위를 보니 서울과 수도권에 버거킹이 많이 있는 것으로 보인다.

카카오맵을 이용하는 방법이 매장수가 500개 이내인 곳에 한해서

효율이 좋은 것 같아 매장수가 적은 햄버거 집에 대해서는

버거킹과 같은 과정을 반복했다.

+ Recent posts