활동내역.zip/개인

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

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

Type: 데이터 수집 / 분석

주제: Web Crawling

사용 IDE: IntelliJ IDEA

사용 언어: Python

사용 패키지: selenium

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


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

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

목표1: 검색 첫 화면 기준 보이는 페이지 수 세는 기능 구현
목표2: 기능들 함수화 및 예외 상황에 대한 코드 보완

코드 작성

A.1. 페이지 세는 함수 제작

A.2. 페이지 정보 예외 상황 대비 

B.1. 마켓컬리 크롤러 함수화

B.2. 페이지 수 만큼 반복하는 기능 넣기

B.3. 추가 변경점


A.1. 페이지 세는 함수 제작

def get_page_count(keyword):
    options = Options()
    options.add_argument("--no-sandbox")
    options.add_argument("--disable-dev-shm-usage")

    browser = webdriver.Chrome(options=options)
    browser.get(f"https://www.kurly.com/search?sword={keyword}")
    browser.implicitly_wait(time_to_wait=3)
    pages = browser.find_element(By.XPATH, '//*[@id="container"]/div/div[2]/div[3]').text

이 부분까지는 웹 페이지를 불러오는 부분이기에 그동안 해봤던 방식처럼 진행하면 된다


A.2. 페이지 정보 예외 상황 대비 

# def get_page_count(keyword):
    pages = pages.splitlines()
    count = []
    for page in pages:
        count.append(int(page))
    count = max(count)
    if count >= 10:
        return 10
    else:
        return count
마켓컬리 페이지 번호부분

 예외 처리를 위와같이 하지 않을 시 생기는 문제점이 있다

1. 별다른 처리 없이 pages를 출력할 경우 1\n2\n3\n4\n5\n6\n7\n8\n9\n10 의 형태가 출력된다

2. String 형태이므로 저 상태에서 max를 줘 봐도 9 이상 높아지지 않는다


B.1. 마켓컬리 크롤러 함수화

def extract_kurly_items(keyword):

함수화 시켜 활용도를 높이도록 한다


B.2. 페이지 수 만큼 반복하는 기능 넣기

pages = get_page_count(keyword)
print("Found", pages, "pages")

results = []
for page in range(1, pages+1):
	final_url = f"{url}{keyword}&page={page}"

page의 수를 위에 만들어두었던 함수에서 가지고 온다

몇 페이지를 찾았는 지 확인 할 코드도 넣어둔다

 

아래에서 진행 될 기존 코드를 페이지 수 만큼 반복시킨다


B.3. 추가 변경점

for element in elements_list:
    if len(element) != 4:
        continue
    title = element[1]
    price = element[2].replace('%', '% 할인, ')
    memo = element[3]

이 부분에서 거의 모든 에러가 났다고 볼 수 있는데,

수많은 시행착오 끝에 element의 길이는 4 또는 그보다 작은 경우의 수만 있다는 것을 확인했다

그래서 데이터를 긁을 현 element의 길이가 다를 경우 가차없이 continue로 돌려버려 현상을 해결했다

ex 에러 예시) [[]] , [ng Soon]


0. 전체 코드 / 실행 결과

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


def get_page_count(keyword):
    options = Options()
    options.add_argument("--no-sandbox")
    options.add_argument("--disable-dev-shm-usage")

    browser = webdriver.Chrome(options=options)
    browser.get(f"https://www.kurly.com/search?sword={keyword}")
    browser.implicitly_wait(time_to_wait=3)
    pages = browser.find_element(By.XPATH, '//*[@id="container"]/div/div[2]/div[3]').text
    # pages는 줄바꿈으로 이루어진 형태의 리스트이다
    # 1\n2\n3\n4\n5\n6\n7\n8\n9\n10
    pages = pages.splitlines()
    count = []
    # int형으로 모두 바꿔주고 최댓값 얻기
    for page in pages:
        count.append(int(page))
    count = max(count)
    # 10페이지 이상 넘어갈 수는 없으니 최대 10까지만 return한다
    if count >= 10:
        return 10
    else:
        return count


def extract_kurly_items(keyword):
    # 화면에 띄워져 있는 페이지의 최대 수를 검색하기 위한 코드
    pages = get_page_count(keyword)
    print("Found", pages, "pages")
    # 페이지 수 만큼 반복시키며 데이터를 가져오는 코드 실행
    results = []
    for page in range(1, pages+1):
        options = Options()
        options.add_argument("--no-sandbox")
        options.add_argument("--disable-dev-shm-usage")
        browser = webdriver.Chrome(options=options)
        url = 'https://www.kurly.com/search?sword='
        final_url = f"{url}{keyword}&page={page}"
        print("Requesting", final_url)
        browser.get(final_url)
        browser.implicitly_wait(time_to_wait=3)

        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 = []
        for item in items:
            items = item.splitlines()
            elements_list.append(items)
        # 뭔가 문제가 생기면 아래 코드를 실행해보면 답이 나온다
        # print(elements_list)
        for element in elements_list:
            # 최대 고전 부분
            # 현재 element 의 길이가 4가 아닌 경우 불량인 배열이므로 폐기
            # 삭제 활용 시 리스트의 길이가 달라져서 실행 불가능
            if len(element) != 4:
                continue
            title = element[1]
            price = element[2].replace('%', '% 할인, ')
            memo = element[3]
            items_data = {
                '상품명': title,
                '가격': price,
                '상품 설명': memo,
            }
            results.append(items_data)
    return results


search = "상추"
ite = extract_kurly_items(search)
print(ite)
정상 출력!

점점 무언가가 만들어지는 느낌이 든다

의미있는 결과물이 나왔으면 좋겠다


다음 편에서 계속됩니다

728x90