티스토리 뷰

728x90
반응형

목차

     

     

    지난 글에서 우리는 크롤링과 셀레늄에 대한 간단한 소개와 그 예를 들어보았다.

     

    그중 셀레늄 소개에서 웹 드라이버를 마치 사용자가 다루듯 할 수 있다는 부분이 있었는데,

     

    이 글에선 그 기능을 간단하게나마 구현해보려고 한다.

     

    keyword_naver_tab_2.py

     

    먼저 지난 글에서 가져왔던 네이버 연관검색어를 검색에서부터 시작해 가져오는 로직을 작성하려고 한다.

     

    지난 글에서와는 다른 방식으로 CSS 셀렉터를 찾아서 시작해보자.

     

    먼저 네이버 모바일 홈페이지에 접근한다.

     

    https://m.naver.com/

     

    네이버 모바일 메인

    네이버 모바일 메인에서 다양한 정보와 유용한 컨텐츠를 만나 보세요

    m.naver.com

    그리고 화면에서 다음과 같이 개발자 도구를 켜고 Cmd+Shift+C를 눌러 검색창을 선택한 뒤,

     

    [Python]복붙으로 끝내는 셀레늄 크롤링(2)

    아래와 같이 해서 셀렉터의 주소를 가져온다.

     

    추가로 모바일 네이버는 여기서 바로 검색이 되는 것이 아니라

     

    검색창을 눌렀을 때 Fake가 아닌 진짜 검색창이 아래와 같이 뜨기 때문에,

     

    위와 같이 하나 더 들어가서 셀렉터를 가져와야 한다.

     

    이후엔 아래와 같이 구현한다.

    from webdriver_config import setup_chrome_driver
    from selenium.webdriver.common.keys import Keys
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC
    from selenium.common.exceptions import TimeoutException
    
    driver = setup_chrome_driver()
    
    query = input("검색어를 입력해주세요: ")
    url = "https://m.search.naver.com/"
    
    driver.get(url)
    
    elements_texts = []
    
    try:
        # 일단 하나의 요소가 나타날 때까지 기다림
        WebDriverWait(driver, 5).until(
            EC.presence_of_element_located(
                (
                    By.CSS_SELECTOR,
                    "#MM_logo > div.sch > section > div > div > form > div.sch_input_wrap",
                )
            )
        )
    
        # 가장 처음 요소 하나만 검색
        search_box = driver.find_element(
            By.CSS_SELECTOR, "#MM_logo > div.sch > section > div > div > form > div.sch_input_wrap"
        )
        search_box.click()
    
        real_search_box = driver.find_element(By.CSS_SELECTOR, "#query")
        real_search_box.send_keys(query + Keys.ENTER)
    
        WebDriverWait(driver, 5).until(
            EC.presence_of_element_located((By.CSS_SELECTOR, "a.clip._slog_visible"))
        )
    
        # 모든 요소 검색
        elements = driver.find_elements(By.CSS_SELECTOR, "a.clip._slog_visible")
    
        # 각 요소의 텍스트 수집
        for element in elements:
            elements_texts.append(element.text)
    
        # 수집된 텍스트 출력
        for text in elements_texts:
            print("Element Found: ", text)
    
    except TimeoutException:
        print("Timed out waiting for element to appear")
    
    finally:
        driver.quit()

    지난 글의 코드와 비교해보면, 먼저

    query = input("검색어를 입력해주세요: ")

    query 변수를 직접 입력받도록 바꾸었고,

        search_box.click()
    
        real_search_box = driver.find_element(By.CSS_SELECTOR, "#query")
        real_search_box.send_keys(query + Keys.ENTER)

    위와 같이 클릭 이벤트와 문자열 입력 과정을 추가해 주었다.

     

    이걸 그대로 복붙해다가 이렇게 저렇게 가지고 놀다 보면 쉽게 와닿을 것 같다.

     

    keyword_naver_shopping_2.py

     

    다음으로 비슷한 작업을 네이버 쇼핑에서 하도록 하자. 먼저 아래와 같이 셀렉터 값을 가져온다.

     

    이하의 설명은 생략하고, 바로 코드로 가면 다음과 같다.

    from webdriver_config import setup_chrome_driver
    from selenium.webdriver.common.keys import Keys
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC
    from selenium.common.exceptions import TimeoutException
    import urllib.parse
    import time
    
    driver = setup_chrome_driver()
    
    query = input("검색어를 입력해주세요: ")
    url = "https://shopping.naver.com/home"
    
    driver.get(url)
    
    decoded_values = []
    
    try:
        # 일단 하나의 요소가 나타날 때까지 기다림
        WebDriverWait(driver, 5).until(
            EC.presence_of_element_located(
                (
                    By.CSS_SELECTOR,
                    "#gnb-gnb > div._gnb_header_area_150KE > div > div._gnbLogo_gnb_logo_3eIAf > div > div._gnbSearch_gnb_search_3O1L2 > form > div._gnbSearch_inner_2Zksb > div > input",
                )
            )
        )
    
        search_box = driver.find_element(
            By.CSS_SELECTOR,
            "#gnb-gnb > div._gnb_header_area_150KE > div > div._gnbLogo_gnb_logo_3eIAf > div > div._gnbSearch_gnb_search_3O1L2 > form > div._gnbSearch_inner_2Zksb > div > input",
        )
    
        search_box.click()
        search_box.send_keys(query)
        time.sleep(1)
        search_box.send_keys(Keys.ARROW_DOWN * 2 + Keys.ENTER)
    
        # data-nclick 속성을 가진 모든 요소 검색
        elements = driver.find_elements(By.CSS_SELECTOR, "[data-nclick^='N=a:rel.keyword,i:']")
    
        # 각 요소를 출력
        for element in elements:
            nclick_value = element.get_attribute("data-nclick")
            # 'i:'와 ',' 사이의 값 추출
            encoded_str = nclick_value.split("i:")[1].split(",")[0]
            decoded_str = urllib.parse.unquote(encoded_str)
            decoded_values.append(decoded_str)
    
        for value in decoded_values:
            print("Decoded value: ", value)
    
    except TimeoutException:
        print("Timed out waiting for element to appear")
    
    finally:
        driver.quit()

    여기서는

        search_box.click()
        search_box.send_keys(query)
        time.sleep(1)
        search_box.send_keys(Keys.ARROW_DOWN * 2 + Keys.ENTER)

     

    이런 식으로 구현해 보았다. 검색어를 입력한 뒤 연관검색어에서 첫 번째 것을 선택한다.

     

    중간의 1초 딜레이는 너무 바로 넘어가면 원하는 크롤링을 못 할 때가 있어서 이렇게 해보았다.

     

    이렇게 해서 지난 글의 크롤링을 모습을 바꿔 다시 구현해 보았다.

     

    이정도만 엮어도 일정 수준 이상의 크롤링은 할 수 있을것이라 생각한다.

     

    만약 다음 글이 있다면 거기선 (1)에서 사용했으나 딱히 설명은 없었던, 여러 요소를 가져오는 방법에 대해 쓸까 한다.

     

    일단 복붙으로 끝내는 셀레늄 크롤링(2), 끝!

    반응형
    댓글
    공지사항
    최근에 올라온 글
    최근에 달린 댓글
    Total
    Today
    Yesterday
    링크
    «   2024/11   »
    1 2
    3 4 5 6 7 8 9
    10 11 12 13 14 15 16
    17 18 19 20 21 22 23
    24 25 26 27 28 29 30
    글 보관함