프로그래밍 언어/Python

쇼핑 트렌드 정보 수집하기

· 코딩마이데이

동일한 역할과 이름을 가진 요소가 여러 개 있을 경우, 인스펙터의 코드 녹화 기능이 제대로 작동하지 않을 수 있습니다. 복잡한 HTML 요소를 찾을 때는 CSS 셀렉터를 사용해야 합니다.

CSS는 HTML 요소를 디자인하는데 사용되며 CSS 셀렉터는 스타일일 적용할 특정 요소를 찾는 규칙을 의미합니다. 아래 표에서 몇 가지 중요한 CSS 셀렉터를 소개합니다. 참고로 표에 나오는 클래스는 HTML 태그의 class 속성 값으로 사용하는 CSS 셀럭터를 의미하며, 파이썬의 클래스와는 다른 개념입니다.

 

CSS 주요 셀럭터

CSS 셀렉터 규칙 사용 예시 의미
태그 이름 img img 태그 전체
[태그 속성] [href] href 속성이 있는 태그 전체
[태그 속성="문자열"] [role="button"] role 속성 값이 "button"과 정확히 일치하는 태그
[태그 속성*="문자열"] [role*="button"] role 속성 값에 "button" 문자열이 포함된 태그
태그1 태그2 p img p 태그의 자식(하위) 태그 중 img 태그
태그1 > 태그2 div > button div 태그의 바로 아래 자식 태그 중 button 태그
#아이디(id) #login id 속성 값이 "login"인 태그
.클래스(class) .black class 속성 값이 "black"인 태그

 

카테고리 선택 자동화하기

이번에는 네이버플러스 스토어의 '베스트쇼핑'에서 쇼핑 카테고리 선택을 자동화하는 코드를 만들어 보겠습니다. CSS 셀럭터를 활용해야 합니다.

이전 절에서 작성한 'step_1_3.py' 파일을 실행하면 크로미움 웹 브라우저가 네이버플러스 스토어에 접속합니다. '베스트상품'으로 이동하면 웹 브라우저를 선택한 상태에서 F12 또는 Ctrl + Alt + | 키를 눌러 개발자 도구를 엽니다.

 

카테고리 선택

'베스트 상품'에서 상품 카테고리를 선택하는 코드를 작성하기 위해 카테고리 버튼의 CSS 셀렉터를 찾아봅시다.

 

01 개발자 도구 왼쪽 상단의 검사 모드 아이콘을 클릭한 후, [패션의류] 메뉴를 클릭하세요.

 

02 개발자 도구의 [요소 Elements] 탭에서 카테고리 메뉴 주변의 HTML 구조를 분석해 봅시다. 여기서 이 버튼을 추출하는 CSS 셀렉터는 li 태그, class 속성의 'imageeCategoryResponsive_list' 문자열, button 태그를 조합한 "li[class*='imageCategoryResponsive_list']>button"입니다.

<ul class="imageCategoryResponsive_set_category__fqRuG">
  <li class="imageCategoryResponsive_list__9mLaf">
    <button>
      <span class="imageCategoryResponsive_text__ctPrh" lang="">
        전체
      </span>
    </button>
  </li>
  ...생략...
</ul>

 

03 인스펙터의 Locator 탭에서 CSS 셀렉터를 사용해 메뉴를 추울할 수 있는지 확인해 봅시다. 인스펙터 하단의 [Locator] 탭을 클릭한 후, 다음과 같이 함수 locator()와 CSS 셀렉터를 입력한 다음 Enter 키를 누르세요.

locator("li[class*='imageCategoryResponsive_list'] > button")

 

04 네이버플러스 스토어의 카테고리가 음영 처리하며, 버튼이 제대로 수출된 것을 확인할 수 있습니다.

 

05 세부 메뉴에는 함수 locator()의 매개변수 has_text에 카테고리를 전달해 선택할 수 있습니다. 예를 들어 [패션의류] 메뉴를 선택하려면 인스펙터 화단의 [Locator] 탭에 다음 코드를 입력한 다음 Enter 키를 누르세요.

locator("li[class*='imageCategoryResponsive_list'] > button", has_text="패션의류")

 

세부 카테고리 선택

이제 세부 카테고리를 선택해 봅시다. 소스 코드 'step_1_3.py'을 실행해서 크로미움 브라우저와 인스펙터를 준비하세요.

 

01 인스펙터의 [Record] 버튼을 클릭해서 녹화를 시작하고, 네이버플러스 스토어의 [모두가 좋아하는] 메뉴를 클릭하세요. 인스펙터에 자동화 코드 page.get_by_role("button", name="모두가 좋아하는 레이어 열기").click()이 입력됩니다.

 

02 목록에서 [10대 여성] 메뉴를 클릭하세요. 인스펙터에 page.get_by_text("10대 여성").click()이 입력됩니다.

 

03 녹화를 중지하기 위해 인스펙터의 [Record] 버튼을 클릭합니다. 빨간색 버튼이 다시 회색으로 돌아오면 녹화가 정상적으로 중지된 것입니다. 인스펙터에서 새로 생성된 코드 두 줄을 드래그하고 Ctrl + C 키를 눌러 복사하세요.

page.get_by_role("button", name="모두가 좋아하는 레이어 열기").click()
page.get_by_text("10대 여성").click()

 

카테고리 메뉴와 세부 조건을 가리키는 CSS 셀럭터를 추출했급니다. 이제 파이썬에서 웹상의 클릭 동작을 자동화하는 코드를 작성하고, 함수로 정의해 추후에 재사용할 수 있도록 하겠습니다.

 

이제 세부 카테고리를 선택하는 코드를 작성해 봅시다. 함수 select_category()는 카테고리를, select_options()는 세부 조건을 선택합니다.

 

실행 중인 프로그램을 종료한 뒤, 비주얼 스튜디오 코드에서 새로운 파일을 만들고 파일명을 'step_2_1.py'로 지정하세요. 다음 코드를 입력한 후, 코드 편집기의 실행 아이콘을 클릭합니다. 크로미움 웹 브라우저가 네이버플러스 스토어에 접속하고 '베스트상품' 페이지의 카테고리가 [패션의류]-[10대 여성]으로 변경됩니다.

 

from playwright.sync_api import Page
from step_1_2 import run_playwright
from step_1_3 import goto_best_goods

def select_category(page: Page, category: str=None): # 05
    selector = "li[class*='imageCategoryResponsive_list'] > button" # 06
    page.locator(selector, has_text=category).click() # 카테고리 버튼 클릭 # 07

def select_options(page: Page, option: str = None): # 09
    page.get_by_role("button", name="모두가 좋아하는 레이어 열기").click() # 10
    page.get_by_text(option).click() # 세부 옵션 버튼 클릭 # 11

if __name__ == "__main__":
    play, browser, page = run_playwright(slow_mo=1000)
    goto_best_goods(page) # 베스트상품 페이지로 이동 # 15
    select_category(page, "패션의류") # 카테고리 클릭 # 16
    select_options(page, "10대 여성") # 세부 옵션 클릭 # 17
    page.pause()
    browser.close()
    play.stop()

 

05 카테고리를 선택하는 함수 select_category()를 정의합니다.

06 카테고리 메뉴의 CSS 셀렉터를 변수 selector에 저장합니다.

07 함수 click()를 호출해서 카테고리 메뉴를 클릭합니다.

09 세부 카테고리를 선택하는 함수 select_options()를 정의합니다. 매개 변수 page에 Page 객체를, option에 세부 카테고리를 지정합니다.

10 [모두가 좋아하는 메뉴]를 클릭합니다.

11 매개변수 option에 전달된 세부 카테고리에 클릭합니다.

15~17 네이버플러스 스토어의 '베스트상품'으로 이동하고 [패션의류]-[10대 여성]을 클릭합니다.