활동내역.zip/개인

[WebCrawling] 웹사이트를 직접 분석해보자 -4편

TMInstaller 2022. 12. 5. 12:00
728x90

Type: 데이터 수집 / 분석

주제: Web Crawling

사용 IDE: IntelliJ IDEA

사용 언어: Python

사용 패키지: selenium

GitHub Link: https://github.com/TMInstaller/WebCrawling_Myblog


설계 - 어떤 기능을 추가할까?

이번 편의 목표는 다음과 같다

목표1: 이전에 완성한 블로그 크롤러 함수화
목표2: 마켓컬리 크롤링을 해보자

 

이번 글에서는 지금까지 만들었던 블로그 크롤러를 함수화하고 다른 사이트의 검색창까지 크롤링해볼까 한다

그렇게 선택한 사이트는 마켓컬리이다

 

기존 작성해 두었던 블로그 크롤러는 함수화 시켜두었다

extracts forder - wwr.py

더보기
# wpc.py
# = web page crawling
from requests import get
from bs4 import BeautifulSoup


def extract_timemapexe_keys(keyword):
    url = "https://time-map-installer.tistory.com/search/"
    response = get(f"{url}{keyword}")
    if response.status_code != 200:
        print("페이지를 불러올 수 없습니다", response.status_code)
    else:
        results = []
        soup = BeautifulSoup(response.text, 'html.parser')
        keys = soup.find_all('div', class_='inner')
        for key_section in keys:
            key_posts = key_section.find_all('div', class_='post-item')
            for post in key_posts:
                span = post.find('a')
                title = span.find('span', class_='title')
                meta = span.find('span', class_='meta')
                date = meta.find('span', class_='date')
                excerpt = span.find('span', class_='excerpt')
                key_data = {
                    'title': title.string,
                    'date': date.string,
                    'prev': excerpt.string
                }
                results.append(key_data)
        return results

코드 작성

1. selenium을 이용해 웹사이트 접속 사전작업

2. 웹사이트 텍스트 정보 가져오기

3. 조건에 맞게 정리하기 위해 상품별 데이터 나누기

4. dict 생성 후 값 다듬고 저장하기


1. selenium을 이용해 웹사이트 접속 사전작업

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By

options = Options()
options.add_argument("--no-sandbox")
options.add_argument("--disable-dev-shm-usage")

아래에서 쓸 selenium 관련 함수를 미리 import 해주었고,

이 부분에 대해서는 강의의 내용을 참고했다

 


2. 웹사이트 텍스트 정보 가져오기

browser = webdriver.Chrome(options=options)
keyword = "고구마"
browser.get(f"https://www.kurly.com/search?sword={keyword}")
browser.implicitly_wait(time_to_wait=5)

elements = browser.find_element(By.XPATH, '//*[@id="container"]/div/div[2]/div[2]').text

이번에 검색해서 가져 올 조건은 고구마이다

마켓컬리의 정보를 얻어오는 데 굉장한 고구마를 먹었기 때문에

키워드도 고구마로 하였다

 

selenium을 이용해서 웹페이지의 정보를 가져오다가 대기시간이 없을 시

정보가 넘어오지 않는 경우가 있어 implicitly_wait를 이용해 대기시간을 주었다

 

이번에는 selenium이 가지고 있는 By와 XPATH를 이용해서 원하는 부분의 경로를

바로 텍스트로 얻어오는 방법을 택했다

가져 올 부분
XPATH 얻는 방법

3. 조건에 맞게 정리하기 위해 상품별 데이터 나누기

items = elements.split('\n샛별배송')
items[0] = items[0][4:]
elements_list = []

for item in items:
    items = item.splitlines()
    elements_list.append(items)

이 부분을 설계하는 데에 있어 가장 많은 시행착오를 겪었다

최종 결과 출력 화면, 현 단계 아님

결과가 위와 같이 출력되게 하기 위한 작업이 생각보다 까다로웠던 것 같다

다행히 모든 상품 부분에 \n샛별배송이 붙어있어서 샛별배송을 기준으로

리스트를 나누는 아이디어를 내어 무사히 1번째 고비를 넘겼다

가져 올 부분

가장 처음에 오는 샛별배송 부분을 빼버리기 위해 슬라이싱으로 값을 변경하기도 했다

그리고 두 번째 고비인 1차원 배열을 2차원 배열로 만드는 작업에서도 굉장히 오래 헤멨던 것 같다

그러다가 상품이 달라질 때마다 줄이 바뀐 것을 확인하고

.splitlines() 을 이용하여 리스트 내의 리스트를 만들어 완성에 한걸음 더 나아갔다

 


4. dict 생성 후 값 다듬고 저장하기

results = []
for element in elements_list:
    title = element[1]
    price = element[2].replace('%', '% 할인, ')
    memo = element[3]
    items_data = {
        '상품명': title,
        '가격': price,
        '상품 설명': memo,
    }
    results.append(items_data)

for result in results:
    print(result, '\n')

리스트 자체를 for문으로 돌릴 때 생기는 편리한 기능 중 하나는

리스트의 index값이 자동으로 정해진다는 것인데, 아래와 같이 설정된다 보면 된다

element = elements_list[element][]

 

그렇게 데이터를 정리하고 가격 부분을 보다가 생긴 문제점이 있었다

출력예시) 11%14,900 원

저 할인 표시가 띄어쓰기 없이 그냥 넘어왔다는 점이다

그래서 위와같은 예외처리 작업을 해 두었다


0. 전체 코드 / 실행 결과

# main.py
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By

# selenium을 이용하여 웹사이트의 정보를 얻어올 준비
options = Options()
options.add_argument("--no-sandbox")
options.add_argument("--disable-dev-shm-usage")

# selenium을 이용하여 검색 했을 때의 결과 페이지 정보를 가져오기
browser = webdriver.Chrome(options=options)
keyword = "고구마"
browser.get(f"https://www.kurly.com/search?sword={keyword}")
# 5초의 대기 시간(페이지가 로딩 될 때까지 기다리는 역할)
browser.implicitly_wait(time_to_wait=5)

# XPATH를 이용하여 검색결과 아이템들의 텍스트 정보만 가져오기
elements = browser.find_element(By.XPATH, '//*[@id="container"]/div/div[2]/div[2]').text

# 모든 상품들이 샛별배송으로 시작하기에 그에 맞는 작업 진행
items = elements.split('\n샛별배송')
items[0] = items[0][4:]
elements_list = []
# 2차원 배열 안에 넣어두기
for item in items:
    items = item.splitlines()
    elements_list.append(items)

# 결과를 담을 results 배열 초기화
results = []
for element in elements_list:
    # 상품명, 가격[변수 처리 작업], 상품 설명 설정
    title = element[1]
    price = element[2].replace('%', '% 할인, ')
    memo = element[3]
    # 설정한 변수들 dict type 으로 저장
    items_data = {
        '상품명': title,
        '가격': price,
        '상품 설명': memo,
    }
    results.append(items_data)

# 결과 출력
for result in results:
    print(result, '\n')
정말 너무 뿌듯한 순간이다

다음 편에서 계속됩니다

 

728x90