파이썬 이것저것/크롤링

[크롤링] GS25 매장 크롤링 -1

agingcurve 2022. 4. 17. 18:50
반응형

거주하고 있는 고양시의 GS25 매장들을 크롤링 하고자 한다. 매장이름, 주소, 기능을 갖고옴

 

목표

 - 페이지 접속과 페이지의 각 요소의 html 속성을 확인

 - 1페이지의 각 요소를 갖고와서 저장하기

url : http://gs25.gsretail.com/gscvs/ko/store-services/locations

 

GS25

일상생활의 중심, 하루의 시작 Lifestyle Platform GS25

gs25.gsretail.com

 

 

- 특히 3번의 기능 을 갖고오는데 많은 고민을 했다. 일단 리스트 형태로 갖고오는것을 목표로 함

 

 

1. 필요 패키지 설치

# 필요 패키지 설치
from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager
from bs4 import BeautifulSoup
import selenium
from selenium import webdriver
import requests
import time
import tqdm

- chrome 드라이버의 경우, 따로 설치하는 방법이 있고, ChromeDriverManger를 설치해서 하는방법 2가지가 있는데, 직접 설치의 경우, 최근 업데이트 이슈로 제대로 구동이 안될수 있다. 따라서 ChromeDriverManger를 설치해서 최신버전으로 실행하는 것을 추천

 

2. 접속

# 크롬 매니저로 접속
driver = webdriver.Chrome(ChromeDriverManager().install())

# GS25 매장찾기 접속
url = "http://gs25.gsretail.com/gscvs/ko/store-services/locations"
driver.get(url)

 

3. HTML 코드분석

 

4. 지역선택

driver.find_element_by_css_selector("#stb1").send_keys("경기도")
driver.find_element_by_css_selector("#stb2").send_keys("고양시")
driver.find_element_by_css_selector("#stb3").send_keys("대화동")
driver.find_element_by_css_selector("#searchButton").click()

5. 가지고올 매장과 리스트 확인

6. 각 요소 확인

## 매장이름
soup.select_one("#storeInfoList > tr:nth-child(1) > td:nth-child(1) > a").text
## 주소
soup.select_one("#storeInfoList > tr:nth-child(1) > td:nth-child(2) > a").text
## 기능 리스트
function_list=[soup.select("#storeInfoList > tr:nth-child(2) > td:nth-child(2) > div > span")[i].text for i in range(len(soup.select("#storeInfoList > tr:nth-child(2) > td:nth-child(2) > div > span")))]​

- 각 매장마다 기능이 다르며, 기능 별로 컬럼을 나누어 가지고 오려고 하니 기능이 너무 많아 코드가 너무 길어지므로 리스트로 갖고와 이를 추후 분석시 구분하여 분석에 사용함

 

7. 매장리스트 크롤링 하여 갖고오기 (for문 사용)

datas = [] # 저장할 리스트
html = driver.page_source
soup = BeautifulSoup(html,"html.parser")# (1)
store_list= len(soup.select("#storeInfoList > tr")) # 페이지에 있는 가게 수
for i in range(1,store_list+1):
    name = soup.select_one(f"#storeInfoList > tr:nth-child({i}) > td:nth-child(1) > a").text #매장이름
    addr = soup.select_one(f"#storeInfoList > tr:nth-child({i}) > td:nth-child(2) > a").text #주소
    function_list = []
    for j in range(len(soup.select(f"#storeInfoList > tr:nth-child({i}) > td:nth-child(2) > div > span"))):
        function_list.append(soup.select(f"#storeInfoList > tr:nth-child({i}) > td:nth-child(2) > div > span")[j].text)

    datas.append({
            "이름":name,
            "주소":addr,
            "기능":function_list
            })

 

 

8. datas 확인 및 data.frame형태로 만들어 저장

GS25 =  pd.DataFrame(datas)
GS25

 

 

9. 페이지별 데이터가 있는 매장들 크롤링 해보기

10. 구성방식

- 순서 : 페이지 갯수를 가지고 옴 -> 하나씩 돌면서 클릭하고 클릭한 페이지의 매장 데이터를 가지고 옴

- 페이지에서 작동하게 하려면 웹페이지 상에서 화면에 나타나야 하므로 스크롤을 아래로 가져가야 함

 

11. 스크롤 하단으로 내리기

# 스크롤 하단으로 내리기
driver.execute_script('window.scrollTo(0, document.body.scrollHeight);')

12. 페이지 숫자 가지고 오기

# 페이지 숫자
page_list = len(soup.select("#pagingTag > a"))

13. 해당 페이지 html 코드가져오기

html = driver.page_source
soup = BeautifulSoup(html,"html.parser")

13. 전체과정

# 여러개 있는 동 크롤링
datas = []
html = driver.page_source
soup = BeautifulSoup(html,"html.parser")
page_list = len(soup.select("#pagingTag > a"))
store_list= len(soup.select("#storeInfoList > tr"))

for m in range(1,page_list+1):
    html = driver.page_source
    soup = BeautifulSoup(html,"html.parser")
    driver.execute_script('window.scrollTo(0, document.body.scrollHeight);')
    driver.find_element_by_css_selector(f"#pagingTag > a:nth-child({m})").click()
    store_list= len(soup.select("#storeInfoList > tr"))
    for j in range(1,store_list+1):
        function_list = []
        for k in range(len(soup.select(f"#storeInfoList > tr:nth-child({j}) > td:nth-child(2) > div > span"))):
            function_list.append(soup.select(f"#storeInfoList > tr:nth-child({j}) > td:nth-child(2) > div > span")[k].text)

        name = soup.select_one(f"#storeInfoList > tr:nth-child({j}) > td:nth-child(1) > a").text #매장이름
        addr = soup.select_one(f"#storeInfoList > tr:nth-child({j}) > td:nth-child(2) > a").text #주소
            #func=[soup.select(f"#storeInfoList > tr:nth-child({j}) > td:nth-child({k}) > div > span")] # 기능리스트
        datas.append({
                "이름":name,
                "주소":addr,
                "기능":function_list
                })
    if m == page_list+1:
        html = driver.page_source
        soup = BeautifulSoup(html,"html.parser")
        store_list= len(soup.select("#storeInfoList > tr"))
        for j in range(1,store_list+1):
            function_list = []
            for k in range(len(soup.select(f"#storeInfoList > tr:nth-child({j}) > td:nth-child(2) > div > span"))):
                function_list.append(soup.select(f"#storeInfoList > tr:nth-child({j}) > td:nth-child(2) > div > span")[k].text)

            name = soup.select_one(f"#storeInfoList > tr:nth-child({j}) > td:nth-child(1) > a").text #매장이름
            addr = soup.select_one(f"#storeInfoList > tr:nth-child({j}) > td:nth-child(2) > a").text #주소
                #func=[soup.select(f"#storeInfoList > tr:nth-child({j}) > td:nth-child({k}) > div > span")] # 기능리스트
            datas.append({
                    "이름":name,
                    "주소":addr,
                    "기능":function_list
                    })

- 다른사람들이 보기엔 복잡한 코드가 되었다. 

- 리스트에서 마지막 페이지가 제대로 크롤링이 안되는 부분이 있어서 if문으로 마지막에 다시한번 반복하는 코드를 실행하였다. 

- 대화동의 21개 데이터가 가져와지게 되었다.