Selenium을 사용하다보면, 클릭했을때 목록이 팝업되고 거기서 값을 선택할 필요가 있을때가 있다.
이럴때 보통 select를 써서 index값을 얻어와서 클릭하곤 하는데, 문제는 선택값이 나오지 않는 경우가 있다.
아래 예시를 보자
네이버 로그인창의 언어선택 드롭다운박스를 보면 id가 주어지고 하위 선택 옵션으로 value가 주어진다.
이럴 경우 단순히 select 메서드를 이용해서 크롤링이 가능한데, 이는 쉬우므로 테스트매니저님의 tistory를 공유하니 아래에서 확인 바란다.
https://testmanager.tistory.com/117
문제는 위처럼 dropdown 목록이 element에 보이지 않는 경우 이다. 예를들어 아래 캡쳐를 보자.
Ocean으로 선택되어있는 combobox의 element를 보아도 option값을 확인 할 수 없다.
색을 변경해보아도 해당 element의 절대적인 값이 변할 뿐 정해진 option value에서 선택하는것이 아니기 때문에, select를 사용할 수 없다. 이를.. 한국에서는 뭐라하는지 못찾겠는데 외국에서는 "Select-React Control"이라고 한다.
한국어로 하면 선택동작조작.. 정도가 될거같다. 아무튼
이럴 땐 해당 combobox를 클릭한 후 execute_script 를 통해 원하는 값을 스크롤하여 찾는 방법을 사용하면 된다.
코드는 아래와 같다.
def find_value(driver):
sleep(0.5)
driver.find_element_by_css_selector('css 셀렉터').click()
option = driver.find_element_by_xpath("//*[text()='검색값']")
driver.execute_script("arguments[0].scrollIntoView();", option)
option.click()
먼저 css 셀렉터를 얻어야하는데 이는 개발자도구를 이용하면 매우 간단하다.
단순히 원하는 element를 우클릭 후 Copy -> Copy selector하면 된다.
이렇게 얻은 selector 은 "#root > div > div.css-4fijr3 > div.css-1y3sizo > div > div > div:nth-child(6) > div.basic-single.css-b62m3t-container > div > div.select__value-container.select__value-container--has-value.css-1d8n9bt"
이다.
그리고 검색하고자 하는 값은 xpath를 이용하는데, "//*[text()='검색값']" 를 통해 앞의 내용 상관없이 text기준으로 검색을 진행하게 되는것이다. 보라색을 선택하기 위해 Purple를 입력하자.
마지막으로 driver.execute_script("arguments[0].scrollIntoView();", option) 는 현재 상태에서 스크롤을 진행하되, option값이 나올때 까지 스크롤을 하는 함수이다.
그리고 option.click( ) 을 통해 해당 값을 클릭한다.
즉, 위 코드가 의미하는것은 콤보박스를 클릭 -> 원하는 값이 나올때 까지 스크롤 -> 원하는 값이 나오면 클릭 하는 과정을 거치는 것이다. 위 코드를 원하는대로 수정하면 아래와 같다.
def find_value(driver):
sleep(0.5)
driver.find_element_by_css_selector('#root > div > div.css-4fijr3 > div.css-1y3sizo > div > div > div:nth-child(6) > div.basic-single.css-b62m3t-container > div > div.select__value-container.select__value-container--has-value.css-1d8n9bt').click()
option = driver.find_element_by_xpath("//*[text()='Purple']")
driver.execute_script("arguments[0].scrollIntoView();", option)
option.click()
위 코드를 앞서만든 크롬드라이버를 자동으로 업데이트하고, 원하는 사이트를 open하는 함수 코드에 적용하여 확인해보자. 전체 코드는 아래와 같다.
>>참고<<
https://trading-for-chicken.tistory.com/19
import os
import chromedriver_autoinstaller as AutoChrome
import shutil
from time import sleep
from selenium import webdriver
# 크롬드라이버 자동 업데이트
def chromedriver_update():
print('크롬드라이버 업데이트 시작')
chrome_ver = AutoChrome.get_chrome_version().split('.')[0]
current_list = os.listdir(os.getcwd())
chrome_list = []
for i in current_list:
path = os.path.join(os.getcwd(), i)
if os.path.isdir(path):
if 'chromedriver.exe' in os.listdir(path):
chrome_list.append(i)
old_version = list(set(chrome_list)-set([chrome_ver]))
for i in old_version:
path = os.path.join(os.getcwd(),i)
shutil.rmtree(path)
if not chrome_ver in current_list:
AutoChrome.install(True)
else : pass
print('크롬드라이버 업데이트 완료')
# 크롬드라이버 경로 찾기
def chrome_driver_path():
print('크롬드라이버 경로 설정')
sleep(0.5)
chrome_ver = AutoChrome.get_chrome_version().split('.')[0]
path = os.path.join(os.getcwd(),chrome_ver)
path = os.path.join(path,'chromedriver.exe')
return str(path)
# 원하는 값 찾기
def find_value(driver):
print('세팅값 적용')
sleep(0.5)
driver.find_element_by_css_selector('#root > div > div.css-4fijr3 > div.css-1y3sizo > div > div > div:nth-child(6) > div.basic-single.css-b62m3t-container > div > div.select__value-container.select__value-container--has-value.css-1d8n9bt').click()
option = driver.find_element_by_xpath("//*[text()='Purple']")
driver.execute_script("arguments[0].scrollIntoView();", option)
option.click()
if __name__ == "__main__":
url = 'https://react-select.com/home'
chromedriver_update()
driver = webdriver.Chrome(chrome_driver_path())
driver.get(url=url)
find_value(driver)
이제 실행해보면 원하는대로 Purple이 선택 되는것을 확인할 수 있다.
'Selenium 웹 크롤링' 카테고리의 다른 글
03. selenium 백그라운드(headless)작업에서 다운로드 안될 때. (0) | 2021.10.05 |
---|---|
02. Selenium을 함수에서 사용시 자동으로 꺼지지 않게 하기. 자동종료방지 (7) | 2021.10.04 |
01. selenium에 필요한 chrome_driver 자동 업데이트 기능 만들기.chromedriver_autoinstaller (1) | 2021.10.01 |