웹 페이지 내에서 웹 요소를 고유하게 식별할 수 있는 주소라고 할 수 있습니다. Locator는 작업을 수행하는데 필요한 웹 요소에 대해 Selenium에 알려주는 웹 요소의 HTML 속성입니다.
쉽게 설명하자면 이렇습니다.
온라인으로 물건을 구매한다고 가정을 하겠습니다. 열심히 온라인으로 구매할 물건을 검색하여 최저가의 물건을 찾았고, 배송지를 입력하고 결제를 합니다.
내가 살 물건은 어떤 행위를 해야할 대상입니다. 해당 대상을 찾았으면 배송지가 어디인지를 입력해야 하는데 그 배송지는 Locator라고 볼 수 있습니다. 해당 Locator 를 찾으면 결제 즉, 행동입니다. 그 행동은 클릭이 될 수 있고 글을 입력할 수 있는 것 등이 될 수 있습니다.
그러면 Locator는 종류가 무엇이고 어떻게 찾을 수 있을까요?
Locator의 종류는 아래와 같습니다.
- ID
- ClassName
- Name
- LinkText
- Xpath
-CSS Selector
다양한 Locator 들 가운데 일반적으로 가장 많이 사용되는 경우는 Xpath와 CSS Selector 입니다. (그 외에도 많이 사용합니다.)
Locator 를 찾는 방법을 알려드리겠습니다.
- 웹 브라우저(chrome)를 열어 놓습니다. (ex. google)
- F12 를 눌러서 개발자도구를 엽니다.
1. 웹 요소를 식별하기 위해 검사 아이콘을 클릭합니다.
2. 검사할 대상(요소)을 클릭합니다.
3. 요소를 기록해둡니다. (ex. CLASS, ID..)
이와 같은 방법을 통하여 요소를 찾을 수 있습니다. 다음 시간에는 Locator 들을 하나씩 사용하는 예시를 알려드리겠습니다.
wait 는 말 그대로 '기다리라' 는 뜻입니다. 여기에는 2가지 타입이 있습니다. 바로 implicitly wait 과 explicitly wait 입니다.
하지만 여기서 implicitly wait 과 explicitly wait 를 배우기 전에 time.sleep 을 배우겠습니다.
time.sleep
time.sleep 은 물리적인 시간을 기다리는 명령어입니다. 사용하는 방법은 time.sleep(초) 를 사용하여 구글 웹페이지가 열린 후 1초, 5.5초, 10초를 기다립니다.
import time from selenium import webdriver from selenium.webdriver.chrome.service import Service from webdriver_manager.chrome import ChromeDriverManager chrome_options = webdriver.ChromeOptions() chrome_options.add_argument('start-maximized') chrome_options.add_argument('incognito') driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=chrome_options) driver.get(url='https://www.google.com/') time.sleep(1) # 1초 기다림 time.sleep(5.5) # 5.5초 기다림 time.sleep(10) # 10초 기다림 driver.quit()
컴퓨터의 사양과 상관없이 무조건 입력한 초가 지나야 다음 동작을 합니다. 그렇기에 적절하게 상황에 따라 사용하면 좋습니다.
Implicitly Wait
implicitly wait 는 웹페이지가 로딩 될때까지 기다리고 다음 동작을 합니다. 쉽게 설명하자면, 예를들어 구글 웹페이지를 오픈했는데 웹페이지를 불러올 때까지 최대 implicitly_wait(초) 까지 기다리라는 뜻입니다.
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument('start-maximized')
chrome_options.add_argument('incognito')
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=chrome_options)
driver.get(url='https://www.google.com/')
driver.implicitly_wait(10) # 10초까지 기다리고 다음 동작
driver.quit()
위 예제에서 implicitly_wait(10)을 했는데 10초동안웹페이지가 로딩될때까지 기다리고 10초가 넘어가면 웹페이지가 로딩이 됐던 안됐던 다음 명령어를 실행하겠다는 뜻입니다.이 또한 상황에 적정한 시간을 설정하면 됩니다.
time.sleep 과 implicitly_wait가 다른 점은 컴퓨터 성능이 좋아서 웹페이지 로딩하는데 1초가 걸렸습니다. 하지만 time.sleep은 무조건 10초를 기다리고 다음 동작은 하고, implicitly_wait는 1초가 됐을 때 다음 동작을 합니다.
Explicitly Wait
implicitly_wait의 경우는 모든 웹페이지가 호출될 때까지 기다리는지만, 컴퓨터 환경(PC성능 또는 서버, 네트워크 등)에 따라 전체가 아닌 일부가 먼저 노출되는 경우가 있습니다. (참고..이것을 동적 DOM이라고 부릅니다.)
예를들어서 implicitly_wait를 사용하여 웹페이지는 1초만에 넘어왔는데 넘어온 웹페이지의 일부분이 자바스크립트로 구현되어 있어서 그 일부분이 화면상에서 렌더링 되느라 비교적 늦게 브라우저에 표시되었다고 가정하면 (ex. 쿠팡 또는 광고 노출) 동작하는데 문제가 발생합니다.
이러한 문제를 해결하기 위해서 explicitly_wait 를 사용합니다. 즉,내가 설정한 것이 표시가 될때까지 뭐뭐 할때까지 기다려라라는 의미입니다.
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.support import expected_conditions as EC
chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument('start-maximized')
chrome_options.add_argument('incognito')
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=chrome_options)
driver.get(url='https://www.google.com/')
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.CLASS_NAME, "gNO89b")))
driver.quit()
time.sleep 과 implicitly_wait 에는 괄호 안에 초를 사용하였지만, explicitly_wait는 사용하는 방법이 조금 다릅니다. element 라는 변수에 WebDriverWait(driver, 10) 즉, driver는 셀레니움 구동한 드라이버가 10초까지 설정한 무엇이 나타날때까지 기다린다는 뜻입니다. 그 다음 .until(EC.presence_of_element_located((By.CLASS_NAME, “gNO89b”))) 의 EC.presence_of_element_located라는 것은 괄호안에 요소가 나타날때까지 기다리라는 의미인데, 괄호안에 요소는 하기와 같습니다. (By.ID, ‘아이디이름’) (By.CLASS_NAME, ‘클래스명’) (By.XPATH, ‘xpath경로’) (By.NAME, ‘네임명’) (By.CSS_SELECTOR, ‘CSS셀렉터’) (By.PARTIAL_LINK_TEXT, ‘텍스트링크일부분’) (By.LINK_TEXT, ‘텍스트링크’)