Selenium 사용 매뉴얼 - 기본 사용 방법 정리
* 이전에 학습하고 사용했던 selenium을 다시 사용해야 하는 상황에서 바뀐 방법을 점검하고 리마인드 하고자 사용 방법에 대한 간단 매뉴얼을 정리한다.
1. 기본 네비게이션 기능
- Selenium에서 기본적인 네비게이션 기능을 수행하는 방법을 설명한다.
1) 웹사이트 열기 (get)
- get(url) 메서드는 지정한 URL의 웹사이트를 불러온다.
from selenium import webdriver
# Chrome WebDriver 실행
options = webdriver.ChromeOptions()
driver = webdriver.Chrome(options=options)
# 웹사이트 열기
driver.get("https://www.example.com")
2) 뒤로 가기 (back)
- 이전 페이지로 이동할 때 사용한다.
driver.back()
3) 앞으로 가기 (forward)
- 앞으로 이동할 때 사용한다.
driver.forward()
4) 페이지 새로고침 (refresh)
- 페이지를 새로고침할 때 사용한다.
driver.refresh()
2. 브라우저 정보 가져오기
- Selenium을 통해 브라우저 정보를 가져오는 방법을 설명한다.
1) 현재 URL 가져오기
current_url = driver.current_url
print(current_url)
2) 페이지 제목 가져오기
title = driver.title
print(title)
3) 페이지 소스 코드 가져오기
page_source = driver.page_source
print(page_source)
3. 기본 설정
- Selenium에서 기본적으로 설정해야 할 사항을 정리한다.
1) 브라우저 옵션 설정
- webdriver.Chrome(): Chrome 브라우저의 인스턴스를 생성한다.
- webdriver.Firefox(): Firefox 브라우저의 인스턴스를 생성한다.
- webdriver.Edge(): Edge 브라우저의 인스턴스를 생성한다.
- webdriver.Safari(): Safari 브라우저의 인스턴스를 생성한다.
options = webdriver.ChromeOptions()
# 브라우저 창을 최대화하여 실행
options.add_argument("--start-maximized")
# 헤드리스 모드로 실행 (UI 없이 백그라운드에서 실행)
options.add_argument("--headless")
# GPU 가속 비활성화 (헤드리스 모드에서 권장)
options.add_argument("--disable-gpu")
# 샌드박스 모드 비활성화 (Linux 환경에서 권장)
options.add_argument("--no-sandbox")
# 공유 메모리 문제 해결 (Docker 또는 리소스 제한 환경에서 권장)
options.add_argument("--disable-dev-shm-usage")
# 브라우저 창 크기 설정 (헤드리스 모드에서 필수)
options.add_argument('window-size=1920x1080')
# 정보 바(infobars) 비활성화
options.add_argument('disable-infobars')
# 확장 프로그램 비활성화
options.add_argument('--disable-extensions')
# 디버거 주소 설정 (원격 디버깅용)
options.add_experimental_option('debuggerAddress', '127.0.0.1:9222')
# 추가 권장 옵션
options.add_argument('--remote-debugging-port=9222')
options.add_argument('--lang=en-US')
options.add_argument('--ignore-certificate-errors')
options.add_argument('--disable-popup-blocking')
# WebDriver 실행
driver = webdriver.Chrome(options=options)
1. 최신 버전에서 폐기되거나 권장되지 않는 옵션
- options.add_experimental_option('excludeSwitches', ['enable-automation'])
- 이 옵션은 ChromeDriver가 자동화된 테스트 소프트웨어에 의해 제어된다는 메시지를 숨기기 위해 사용되었다.
- 최신 버전에서는 --disable-blink-features=AutomationControlled와 함께 사용되지 않을 수 있다.
- 대체 옵션: options.add_argument('--disable-blink-features=AutomationControlled')를 사용면 된다.
- options.add_experimental_option('useAutomationExtension', False)
- 이 옵션은 자동화 확장 프로그램을 비활성화하기 위해 사용되었다.
- 최신 버전에서는 더 이상 필요하지 않을 수 있다.
- options.add_argument('--disable-blink-features=AutomationControlled')
- 이 옵션은 Blink 엔진의 자동화 제어 기능을 비활성화한다.
- 최신 버전에서는 ChromeDriver가 자동으로 이를 처리하므로 명시적으로 설정할 필요가 없을 수 있다.
2. 추가 권장 옵션
- options.add_argument('--remote-debugging-port=9222')
- 원격 디버깅을 활성화합니다. debuggerAddress와 함께 사용할 수 있다.
- options.add_argument('--lang=en-US')
- 브라우저의 언어를 설정합니다. 테스트 환경에서 언어를 고정할 때 유용하다.
- options.add_argument('--ignore-certificate-errors')
- SSL 인증서 오류를 무시합니다. 테스트 환경에서 유용하다.
- options.add_argument('--disable-popup-blocking')
- 팝업 창을 차단하지 않도록 설정한다.
2) 환경별 설정 방법
환경 | 설정 옵션 | 설명 |
일반적인 크롤링 | --start-maximized | 브라우저 창을 최대화하여 실행합니다. |
--disable-gpu | GPU 가속을 비활성화합니다. (헤드리스 모드가 아닐 때도 안정성을 위해 권장) | |
--disable-infobars | 정보 바(infobars)를 비활성화합니다. (예: "Chrome이 자동화된 테스트 소프트웨어에 의해 제어됩니다." 메시지 숨김) | |
--disable-extensions | 확장 프로그램을 비활성화합니다. | |
--lang=en-US | 브라우저 언어를 영어(미국)로 설정합니다. | |
--ignore-certificate-errors | SSL 인증서 오류를 무시합니다. | |
--disable-popup-blocking | 팝업 창을 차단하지 않도록 설정합니다. | |
--disable-notifications | 웹사이트 알림을 비활성화하여 불필요한 UI 요소를 제거합니다. | |
--disable-sync | Chrome의 동기화 기능을 비활성화하여 리소스 사용을 줄입니다. | |
--disable-translate | 자동 번역 기능을 비활성화하여 불필요한 로드 방지 | |
--disk-cache-size=0 | 디스크 캐시 사용을 비활성화하여 속도를 높입니다. | |
--disable-logging | 불필요한 로그 생성을 방지하여 성능을 최적화합니다. | |
--autoplay-policy=no-user-gesture-required | 비디오 자동 재생을 허용하여 일부 사이트에서 크롤링 문제 방지 | |
서버 환경 (GUI 없음) | --headless=new | 헤드리스 모드로 실행합니다. (UI 없이 백그라운드에서 실행) |
--no-sandbox | 샌드박스 모드를 비활성화합니다. (Linux 환경에서 권장) | |
--disable-dev-shm-usage | 공유 메모리 문제를 해결합니다. (Docker 또는 리소스 제한 환경에서 권장) | |
--disable-gpu | GPU 가속을 비활성화합니다. (헤드리스 모드에서 필수) | |
window-size=1920x1080 | 브라우저 창 크기를 설정합니다. (헤드리스 모드에서 필수) | |
--remote-debugging-port=9222 | 원격 디버깅을 활성화합니다. (디버깅이 필요한 경우) | |
--disable-software-rasterizer | GPU가 없을 때 소프트웨어 렌더링을 비활성화하여 속도를 개선합니다. | |
--single-process | 모든 작업을 단일 프로세스로 실행하여 리소스를 절약합니다. | |
--no-zygote | 불필요한 프로세스를 생성하지 않도록 설정하여 메모리 사용을 줄입니다. | |
--disable-features=site-per-process | 프로세스 격리를 비활성화하여 리소스를 절약합니다. | |
--log-level=3 | 불필요한 로그 출력을 최소화하여 성능을 최적화합니다. | |
빠른 실행 환경 | --disable-extensions | 확장 프로그램을 비활성화합니다. (성능 향상) |
--disable-infobars | 정보 바를 비활성화합니다. (불필요한 UI 요소 제거) | |
--disable-blink-features=AutomationControlled | Selenium 탐지를 방지합니다. | |
--disable-background-networking | 백그라운드 네트워크 요청을 비활성화하여 속도 개선 | |
--disable-background-timer-throttling | 백그라운드 작업의 속도 제한을 해제 | |
--disable-backgrounding-occluded-windows | 가려진 창의 백그라운드 리소스 사용 제한을 비활성화 | |
--disable-renderer-backgrounding | 렌더러 프로세스의 백그라운드 동작을 비활성화하여 속도 개선 | |
--user-agent="Mozilla/5.0 ..." | User-Agent를 변경하여 탐지 방지 | |
--disable-notifications | 알림을 비활성화합니다. (팝업 방지) | |
--disable-web-security | 웹 보안을 비활성화합니다. (테스트 환경에서만 사용, CORS 문제 해결) | |
--disable-logging | 로깅을 비활성화합니다. (콘솔 로그 감소) | |
--log-level=3 | 로그 레벨을 최소화합니다. (에러 로그만 출력) | |
--silent | 불필요한 출력을 비활성화합니다. (콘솔 출력 감소) | |
--mute-audio | 오디오를 음소거합니다. (불필요한 리소스 사용 방지) |
3) 사람처럼 인식되도록 설정하는 방법
1. User Agent 설정: 이미 코드에 구현되어 있는 것처럼 fake-useragent 라이브러리를 사용하여 랜덤한 User Agent를 지정할 수 있다.
from fake_useragent import UserAgent
ua = UserAgent()
user_agent = ua.random # 랜덤 User Agent 가져오기
options.add_argument(f'user-agent={user_agent}')
2. 창 크기 랜덤화: 다양한 창 크기로 설정하여 일반 사용자와 유사하게 만들 수 있다.
- option을 이용한 크기 변경
window_sizes = [(1366, 768), (1920, 1080), (1440, 900), (1536, 864)]
window_size = random.choice(window_sizes)
options.add_argument(f'--window-size={window_size[0]},{window_size[1]}')
- driver의 메소드를 이용하여 크기 변경
driver.maximize_window() # 최대크기
driver.minimize_window() # 최소크기
driver.set_window_size(600, 600)
4) 자동화 감지 방지 방법
1. navigator.webdriver 속성 제거: 자동화 스크립트 감지를 피하기 위해 navigator.webdriver 속성을 제거한다.
driver.execute_script("Object.defineProperty(navigator, 'webdriver', {get: () => undefined})")
2. DevTools Protocol 활성화: 네트워크 요청 제어를 위해 DevTools Protocol을 활성화한다.
driver.execute_cdp_cmd("Network.enable", {})
driver.execute_cdp_cmd("Network.setBlockedURLs", {
"urls": ["*.png", "*.jpg", "*.jpeg", "*.gif", "*.css", "*.js", "*.woff", "*.svg"]
})
5) 경고 창 다루기(alerts)
- 경고창에서 수락/거절을 누르거나, 경고창의 내용을 출력, 혹은 경고창에 특정 키 입력을 보낸다.
from selenium.webdriver.common.alert import Alert
Alert(driver).accept()
Alert(driver).dismiss()
print(Alert(driver).text)
Alert(driver).send_keys(keysToSend=Keys.ESCAPE)
6) 프록시(Proxy) 설정 및 제어 방법
1. ChromeOptions을 활용한 프록시 설정
- 프록시 서버를 지정하여 크롬 드라이버를 실행할 수 있다.
- --proxy-server={proxy}: 특정 프록시 서버를 설정하는 옵션이다.
- driver.get("https://www.whatismyip.com/"): 현재 사용 중인 IP를 확인할 수 있는 사이트를 방문하여 프록시가 정상 작동하는지 테스트한다.
from selenium import webdriver
proxy = "123.456.789.000:8080" # 사용할 프록시 주소
chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument(f'--proxy-server={proxy}')
# Chrome WebDriver 실행
driver = webdriver.Chrome(options=chrome_options)
driver.get("https://www.whatismyip.com/") # IP 확인을 위한 웹사이트 방문
2. WebDriverManager를 이용한 동적 프록시 설정
- ChromeDriverManager().install(): 최신 버전의 크롬 드라이버를 자동 설치하여 사용할 수 있도록 설정한다.
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
proxy = "123.456.789.000:8080"
chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument(f'--proxy-server={proxy}')
# WebDriverManager를 사용하여 Chrome 드라이버 실행
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=chrome_options)
driver.get("https://www.whatismyip.com/")
3. HTTP, HTTPS, SOCKS 프록시 설정
프록시 유형 | 옵션 예제 |
HTTP 프록시 | --proxy-server=http://123.456.789.000:8080 |
HTTPS 프록시 | --proxy-server=https://123.456.789.000:8080 |
SOCKS5 프록시 | --proxy-server=socks5://123.456.789.000:1080 |
proxy = "socks5://123.456.789.000:1080" # SOCKS5 프록시 설정
chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument(f'--proxy-server={proxy}')
driver = webdriver.Chrome(options=chrome_options)
driver.get("https://www.whatismyip.com/")
4. 사용자 인증이 필요한 프록시 설정
- Selenium에서는 기본적으로 인증을 처리할 수 없지만, selenium-wire 패키지를 사용하여 이를 해결할 수 있다.
- 설치
pip install selenium-wire
- 코드
- elenium-wire는 네트워크 요청을 가로채고 조작할 수 있도록 도와주는 라이브러리이다.
- 사용자 인증이 필요한 프록시를 설정할 때 사용한다.
from seleniumwire import webdriver
proxy_host = "123.456.789.000"
proxy_port = "8080"
proxy_user = "username"
proxy_pass = "password"
options = {
'proxy': {
'http': f'http://{proxy_user}:{proxy_pass}@{proxy_host}:{proxy_port}',
'https': f'https://{proxy_user}:{proxy_pass}@{proxy_host}:{proxy_port}',
'no_proxy': 'localhost,127.0.0.1' # 프록시 예외 설정
}
}
driver = webdriver.Chrome(seleniumwire_options=options)
driver.get("https://www.whatismyip.com/")
5. 프록시를 무작위로 변경하여 사용하기
- 웹사이트에서 동일한 IP로 여러 번 요청하면 차단될 가능성이 있다. 이를 방지하기 위해 프록시 리스트를 무작위로 선택하여 사용할 수 있다.
- random.choice(proxy_list): 무작위로 프록시를 선택하여 사용할 수 있다.
- IP 차단을 방지하는 데 유용하다.
import random
from selenium import webdriver
# 여러 개의 프록시 리스트
proxy_list = [
"123.456.789.000:8080",
"234.567.890.111:8080",
"345.678.901.222:8080"
]
# 무작위 프록시 선택
selected_proxy = random.choice(proxy_list)
chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument(f'--proxy-server={selected_proxy}')
driver = webdriver.Chrome(options=chrome_options)
driver.get("https://www.whatismyip.com/")
6. Selenium에서 프록시를 동적으로 변경하는 방법
- 실행 중에 프록시를 동적으로 변경하고 싶다면, DevTools Protocol을 사용하여 설정할 수 있다.
- execute_cdp_cmd("Network.setExtraHTTPHeaders", {...}): 실행 중 프록시 설정을 변경할 수 있다.
from selenium import webdriver
chrome_options = webdriver.ChromeOptions()
driver = webdriver.Chrome(options=chrome_options)
# 프록시 설정 변경
proxy = "123.456.789.000:8080"
driver.execute_cdp_cmd("Network.setExtraHTTPHeaders", {
"headers": {
"Proxy-Authorization": f"Basic {proxy}"
}
})
driver.get("https://www.whatismyip.com/")
7. 프록시 설정이 적용되었는지 확인하는 방법
- 프록시가 제대로 설정되었는지 확인하려면, http://api.ipify.org 와 같은 IP 확인 사이트를 사용하면 된다.
- requests.get("http://api.ipify.org", proxies=proxies): 현재 사용 중인 IP 주소를 확인 한다.
import requests
proxy = "123.456.789.000:8080"
proxies = {
"http": f"http://{proxy}",
"https": f"https://{proxy}"
}
response = requests.get("http://api.ipify.org", proxies=proxies)
print("현재 IP:", response.text)
4. Select 클래스를 이용하여 옵션 선택 및 제출하는 방법
selenium.webdriver.support.ui.Select
- 이 클래스는 드롭다운 메뉴나 리스트 박스와 같은 <select> 요소를 쉽게 제어할 수 있게 해준다.
1) 옵션 선택 및 제출(submit) 방법
1. 옵션 선택
from selenium import webdriver
from selenium.webdriver.support.ui import Select
# 웹드라이버 초기화
driver = webdriver.Chrome()
# 웹 페이지 열기
driver.get('http://example.com')
# <select> 요소 찾기
select_element = Select(driver.find_element_by_id('select_id'))
# 옵션 선택 방법
select_element.select_by_visible_text('Option Text') # 텍스트로 선택
select_element.select_by_value('option_value') # 값으로 선택
select_element.select_by_index(1) # 인덱스로 선택
2. 제출(submit)
# 제출 방법 1: click() 사용
submit_button = driver.find_element_by_id('submit_button_id')
submit_button.click()
# 제출 방법 2: submit() 사용
form_element = driver.find_element_by_id('form_id')
form_element.submit()
2) 특정 선택 해제 및 전부 해제
1. 특정 선택 해제
# 특정 옵션 해제 (멀티 선택 가능한 경우)
select_element.deselect_by_visible_text('Option Text') # 텍스트로 해제
select_element.deselect_by_value('option_value') # 값으로 해제
select_element.deselect_by_index(1) # 인덱스로 해제
2. 전부 해제
# 모든 옵션 해제 (멀티 선택 가능한 경우)
select_element.deselect_all()
3) 선택된 옵션 리스트 얻기
# 선택된 옵션 리스트 얻기
selected_options = select_element.all_selected_options
for option in selected_options:
print(option.text)
4) 첫번째 선택된 옵션 얻기
# 첫번째 선택된 옵션 얻기
first_selected_option = select_element.first_selected_option
print(first_selected_option.text)
5) 가능한 옵션 모두 보기
# 가능한 모든 옵션 보기
all_options = select_element.options
for option in all_options:
print(option.text)
6) 제출을 위한 방법: click() vs submit()
1. click()
- click() 메서드는 버튼이나 링크와 같은 요소를 클릭할 때 사용된다.
- 일반적으로 폼 제출 버튼을 클릭할 때 사용한다.
2. submit()
- submit() 메서드는 폼 요소(<form>)에 대해 사용된다.
- 폼 내부의 어떤 요소에서도 호출할 수 있으며, 폼을 제출한다.
- 폼 내부에 <input type="submit"> 버튼이 없어도 폼을 제출할 수 있다.
- 예제 코드
from selenium import webdriver
from selenium.webdriver.support.ui import Select
# 웹드라이버 초기화
driver = webdriver.Chrome()
# 웹 페이지 열기
driver.get('http://example.com')
# <select> 요소 찾기
select_element = Select(driver.find_element_by_id('select_id'))
# 옵션 선택
select_element.select_by_visible_text('Option Text')
# 선택된 옵션 리스트 얻기
selected_options = select_element.all_selected_options
for option in selected_options:
print(option.text)
# 첫번째 선택된 옵션 얻기
first_selected_option = select_element.first_selected_option
print(first_selected_option.text)
# 가능한 모든 옵션 보기
all_options = select_element.options
for option in all_options:
print(option.text)
# 제출 방법 1: click() 사용
submit_button = driver.find_element_by_id('submit_button_id')
submit_button.click()
# 제출 방법 2: submit() 사용
form_element = driver.find_element_by_id('form_id')
form_element.submit()
# 웹드라이버 종료
driver.quit()
5. WebDriverWait & Expected Conditions(명시적 대기) & Implicit Waits(암묵적 대기)
- 웹사이트에서 요소가 나타날 때까지 기다리는 방법을 설명한다.
1) 명시적 대기 (WebDriverWait)
- 개념: 특정 조건이 충족될 때까지 명시적으로 대기한다. 조건은 WebDriverWait와 expected_conditions를 사용하여 정의한다.
- 사용 시나리오:
- 특정 요소가 로드될 때까지 기다릴 때
- 요소가 클릭 가능해질 때까지 기다릴 때
- AJAX 요청이 완료될 때까지 기다릴 때
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
wait = WebDriverWait(driver, 10)
element = wait.until(EC.presence_of_element_located((By.ID, "element_id")))
- 기본 예제
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# WebDriver 초기화
driver = webdriver.Chrome()
try:
# 페이지 열기
driver.get("https://example.com")
# 명시적 대기: 요소가 로드될 때까지 최대 10초 대기
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.ID, "element-id"))
)
print("요소가 로드되었습니다!")
# 요소 클릭
element.click()
finally:
# WebDriver 종료
driver.quit()
- 실무 예제
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# WebDriver 초기화
driver = webdriver.Chrome()
try:
# 로그인 페이지 열기
driver.get("https://example.com/login")
# 사용자 이름 입력 필드가 나타날 때까지 대기
username_field = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.ID, "username"))
)
username_field.send_keys("user@example.com")
# 비밀번호 입력 필드가 나타날 때까지 대기
password_field = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.ID, "password"))
)
password_field.send_keys("password123")
# 로그인 버튼이 클릭 가능해질 때까지 대기
login_button = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.ID, "login-btn"))
)
login_button.click()
# 로그인 후 대시보드 페이지가 로드될 때까지 대기
WebDriverWait(driver, 10).until(
EC.title_contains("Dashboard")
)
print("로그인 성공! 대시보드 페이지가 로드되었습니다.")
finally:
# WebDriver 종료
driver.quit()
2) 자주 사용되는 expected_conditions
메서드 | 설명 | 사용 예시 |
title_is(title) | 페이지의 제목이 정확히 일치하는지 확인합니다. | EC.title_is("Welcome") |
title_contains(partial_title) | 페이지의 제목에 특정 문자열이 포함되어 있는지 확인합니다. | EC.title_contains("Welcome") |
presence_of_element_located(locator) | 요소가 DOM에 존재하는지 확인합니다. (보이지 않아도 됨) | EC.presence_of_element_located((By.ID, "element-id")) |
visibility_of_element_located(locator) | 요소가 DOM에 존재하고 보이는지 확인합니다. | EC.visibility_of_element_located((By.ID, "element-id")) |
visibility_of(element) | 특정 요소가 보이는지 확인합니다. | EC.visibility_of(element) |
presence_of_all_elements_located(locator) | 모든 요소가 DOM에 존재하는지 확인합니다. | EC.presence_of_all_elements_located((By.CLASS_NAME, "item")) |
text_to_be_present_in_element(locator, text) | 요소 내에 특정 텍스트가 포함되어 있는지 확인합니다. | EC.text_to_be_present_in_element((By.ID, "message"), "Success") |
text_to_be_present_in_element_value(locator, text) | 요소의 value 속성에 특정 텍스트가 포함되어 있는지 확인합니다. | EC.text_to_be_present_in_element_value((By.ID, "input"), "Hello") |
frame_to_be_available_and_switch_to_it(locator) | 프레임이 사용 가능해지고, 해당 프레임으로 전환합니다. | EC.frame_to_be_available_and_switch_to_it((By.ID, "iframe-id")) |
invisibility_of_element_located(locator) | 요소가 보이지 않거나 DOM에 존재하지 않는지 확인합니다. | EC.invisibility_of_element_located((By.ID, "loading-spinner")) |
element_to_be_clickable(locator) | 요소가 클릭 가능한 상태인지 확인합니다. | EC.element_to_be_clickable((By.ID, "submit-btn")) |
staleness_of(element) | 요소가 DOM에서 제거되었는지 확인합니다. | EC.staleness_of(old_element) |
element_to_be_selected(element) | 요소가 선택된 상태인지 확인합니다. (체크박스, 라디오 버튼 등) | EC.element_to_be_selected(element) |
element_located_to_be_selected(locator) | 요소가 선택된 상태인지 확인합니다. (체크박스, 라디오 버튼 등) | EC.element_located_to_be_selected((By.ID, "checkbox")) |
element_selection_state_to_be(element, is_selected) | 요소의 선택 상태가 특정 상태인지 확인합니다. | EC.element_selection_state_to_be(element, True) |
element_located_selection_state_to_be(locator, is_selected) | 요소의 선택 상태가 특정 상태인지 확인합니다. | EC.element_located_selection_state_to_be((By.ID, "checkbox"), True) |
alert_is_present() | 알림 창이 나타났는지 확인합니다. | EC.alert_is_present() |
- 사용 예시 코드
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# WebDriver 초기화
driver = webdriver.Chrome()
try:
# 페이지 열기
driver.get("https://example.com")
# 1. title_is 예시
WebDriverWait(driver, 10).until(EC.title_is("Example Domain"))
print("페이지 제목이 'Example Domain'입니다.")
# 2. presence_of_element_located 예시
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.ID, "element-id"))
)
print("요소가 DOM에 존재합니다.")
# 3. visibility_of_element_located 예시
visible_element = WebDriverWait(driver, 10).until(
EC.visibility_of_element_located((By.ID, "visible-element"))
)
print("요소가 보입니다.")
# 4. text_to_be_present_in_element 예시
WebDriverWait(driver, 10).until(
EC.text_to_be_present_in_element((By.ID, "message"), "Success")
)
print("요소에 'Success' 텍스트가 포함되어 있습니다.")
# 5. element_to_be_clickable 예시
clickable_element = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.ID, "submit-btn"))
)
clickable_element.click()
print("요소가 클릭되었습니다.")
# 6. alert_is_present 예시
WebDriverWait(driver, 10).until(EC.alert_is_present())
alert = driver.switch_to.alert
alert.accept()
print("알림 창이 처리되었습니다.")
finally:
# WebDriver 종료
driver.quit()
3) 암묵적 대기 (Implicit Wait)
- 개념: 모든 요소를 찾을 때 일정 시간 동안 대기한다. 요소가 즉시 발견되면 대기하지 않고, 발견되지 않으면 설정한 시간만큼 대기한다.
- 사용 시나리오:
- 모든 요소에 대해 일관된 대기 시간을 적용할 때
- 간단한 스크립트에서 사용할 때
- 기본 예제
from selenium import webdriver
from selenium.webdriver.common.by import By
# WebDriver 초기화
driver = webdriver.Chrome()
# 암묵적 대기 설정 (10초)
driver.implicitly_wait(10)
try:
# 페이지 열기
driver.get("https://example.com")
# 요소 찾기 (암묵적 대기가 적용됨)
element = driver.find_element(By.ID, "element-id")
print("요소가 로드되었습니다!")
# 요소 클릭
element.click()
finally:
# WebDriver 종료
driver.quit()
- 실무 예제
from selenium import webdriver
from selenium.webdriver.common.by import By
# WebDriver 초기화
driver = webdriver.Chrome()
# 암묵적 대기 설정 (10초)
driver.implicitly_wait(10)
try:
# 제품 목록 페이지 열기
driver.get("https://example.com/products")
# 제품 이름 요소 찾기 (암묵적 대기가 적용됨)
product_names = driver.find_elements(By.CLASS_NAME, "product-name")
# 제품 이름 출력
for name in product_names:
print(name.text)
# 장바구니 버튼이 나타날 때까지 대기 (암묵적 대기가 적용됨)
add_to_cart_button = driver.find_element(By.ID, "add-to-cart")
add_to_cart_button.click()
# 장바구니 페이지로 이동할 때까지 대기 (암묵적 대기가 적용됨)
driver.find_element(By.ID, "cart-page-link").click()
print("장바구니 페이지로 이동했습니다.")
finally:
# WebDriver 종료
driver.quit()
4) 명시적 대기 vs 암묵적 대기
항목 | 명시적 대기 (Explicit Wait) | 암묵적 대기 (Implicit Wait) |
적용 범위 | 특정 조건에만 적용 | 모든 요소 찾기에 적용 |
유연성 | 조건을 세부적으로 설정 가능 | 모든 요소에 동일한 대기 시간 적용 |
성능 | 필요한 경우에만 대기하므로 효율적 | 불필요한 대기 시간이 발생할 수 있음 |
사용 시나리오 | 특정 요소가 로드될 때까지 기다릴 때 | 간단한 스크립트나 모든 요소에 동일한 대기 시간이 필요할 때 |
6. 요소 선택 (타겟 설정)
- 웹 페이지에서 요소를 선택하는 다양한 방법을 설명한다.
1) find_element 와 find_elements
from selenium.webdriver.common.by import By
# 태그 선택자
element = driver.find_element(By.TAG_NAME, "p")
# 클래스 선택자
element = driver.find_element(By.CLASS_NAME, "class_name")
# 아이디 선택자
element = driver.find_element(By.ID, "element_id")
# 자식 요소 선택
element = driver.find_element(By.CSS_SELECTOR, "div > p")
# 여러 개의 요소 찾기
elements = driver.find_elements(By.CLASS_NAME, "class_name")
for el in elements:
print(el.text)
2) XPath를 사용한 요소 찾기
# 절대 경로
el = driver.find_element(By.XPATH, "/html/body/div/h1")
# 상대 경로
el = driver.find_element(By.XPATH, "//h1")
# 특정 속성으로 요소 찾기
el = driver.find_element(By.XPATH, "//input[@name='username']")
- 표현식
표현식 | 설명 |
nodename | nodename을 name으로 갖는 모든 요소 선택 |
/ | root 요소에서 선택 |
// | 현재 요소의 자손 요소를 선택 |
. | 현재 요소를 선택 |
.. | 현재 요소의 부모 요소를 선택 |
@ | 속성(attibutes)를 선택 |
* | 모든 요소에 매치됨 |
@* | 모든 속성 요소에 매치됨 |
node() | 모든 종류의 모든 요소에 매치됨 |
| | OR 조건의 기능 |
- 표현식 사용 예시
표현식 | 설명 |
/div | root 요소의 div 요소 |
./div | 현재 요소의 자식 요소 중 div 요소 |
/* | name에 상관없이 root 요소를 선택 |
./* 또는 * | context 요소의 모든 자식 요소를 선택 |
//div | 현재 웹페이지에서 모든 div 요소를 선택 |
.//div | 현재 요소의 모든 자손 div 요소를 선택 |
//* | 현재 웹페이지의 모든 요소를 선택 |
.//* | 현재 요소의 모든 자손 요소를 선택 |
/div/p[0] | root > div > p 요소 중 첫 번째 p 요소를 선택 |
/div/p[position()<3] | root > div > p 요소 중 첫 두 p 요소를 선택 |
/div/p[last()] | root > div > p 요소 중 마지막 p 요소를 선택 |
/bookstore/book[price>35.00] | root > bookstore > book 요소 중 price 속성이 35.00 초과인 요소들을 선택 |
//*[@id="tsf"]/div[2]/ | id가 tsf인 모든 요소의 자식 div 요소 중 3번째 요소를 선택 |
//title | //price | title 또는 price 요소를 선택 |
3) CSS 선택자 사용하기
# 특정 속성 선택
element = driver.find_element(By.CSS_SELECTOR, "[type='submit']")
# 다중 조건 선택
element = driver.find_element(By.CSS_SELECTOR, "button.submit-btn")
4) 링크 텍스트를 사용한 선택
# 정확한 링크 텍스트로 찾기
element = driver.find_element(By.LINK_TEXT, "Click Here")
5) 계층적 요소 선택
# 부모 요소 내 자식 요소 찾기
parent = driver.find_element(By.ID, "parent_id")
child = parent.find_element(By.TAG_NAME, "p")
7. 동적 웹사이트 크롤링 및 페이지네이션
1) JavaScript 실행을 통한 데이터 로딩
data = driver.execute_script("return document.getElementById('data').innerText;")
2) 자동 스크롤
last_height = driver.execute_script("return document.body.scrollHeight")
while True:
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
time.sleep(2)
new_height = driver.execute_script("return document.body.scrollHeight")
if new_height == last_height:
break
last_height = new_height
3) 페이지네이션
while True:
try:
next_button = driver.find_element(By.LINK_TEXT, "Next")
next_button.click()
time.sleep(2)
except:
break
8. webdriver, WebElement, By, Keys, ActionChains, WebDriverWait, expected_conditions 클래스 정리
1) 주요 클래스의 메소드 테이블
주요 클래스 | 클래스별 주요 메소드 | 메소드 기능 설명 |
webdriver | get(url) | 특정 URL로 이동 |
close() | 현재 브라우저 창 닫기 | |
quit() | 모든 브라우저 창 닫고 WebDriver 종료 | |
find_element(by, value) | 단일 요소 찾기 | |
find_elements(by, value) | 여러 요소 찾기 | |
get_cookies() | 모든 쿠키 반환 | |
add_cookie(cookie_dict) | 쿠키 추가 | |
delete_cookie(name) | 특정 쿠키 삭제 | |
delete_all_cookies() | 모든 쿠키 삭제 | |
execute_script(script, *args) | JavaScript 코드 실행 | |
save_screenshot(filename) | 페이지 스크린샷 저장 | |
WebElement | click() | 요소 클릭 |
send_keys(*value) | 키보드 입력 | |
clear() | 요소 내용 지우기 | |
get_attribute(name) | 요소 속성 값 반환 | |
is_displayed() | 요소 표시 여부 반환 | |
is_enabled() | 요소 활성화 여부 반환 | |
is_selected() | 요소 선택 여부 반환 | |
By | ID | ID로 요소 찾기 |
NAME | 이름으로 요소 찾기 | |
CLASS_NAME | 클래스 이름으로 요소 찾기 | |
TAG_NAME | 태그 이름으로 요소 찾기 | |
CSS_SELECTOR | CSS 셀렉터로 요소 찾기 | |
XPATH | XPath로 요소 찾기 | |
Keys | RETURN | 리턴 키 |
ENTER | 엔터 키 | |
TAB | 탭 키 | |
ESCAPE | ESC 키 | |
BACK_SPACE | 백스페이스 키 | |
SPACE | 스페이스 바 | |
ARROW_UP, ARROW_DOWN, ARROW_LEFT, ARROW_RIGHT | 방향키 (위, 아래, 왼쪽, 오른쪽) | |
ActionChains | click(on_element=None) | 인자로 주어진 요소를 왼쪽 클릭 |
click_and_hold(on_element=None) | 인자로 주어진 요소를 왼쪽 클릭하고 누르고 있음 | |
release(on_element=None) | 마우스를 주어진 요소에서 뗌 | |
context_click(on_element=None) | 인자로 주어진 요소를 오른쪽 클릭 | |
double_click(on_element=None) | 인자로 주어진 요소를 왼쪽 더블클릭 | |
drag_and_drop(source, target) | source 요소에서 마우스 왼쪽 클릭하여 계속 누른 채로 target까지 이동한 뒤 마우스를 놓음 | |
drag_and_drop_by_offset(source, xoffset, yoffset) | source 요소에서 마우스 왼쪽 클릭하여 계속 누른 채로 offset만큼 이동한 뒤 마우스를 놓음 | |
key_down(value, element=None) | value로 주어진 키를 누르고 떼지 않음 | |
key_up(value, element=None) | value로 주어진 키를 뗌 | |
move_to_element(to_element) | 마우스를 해당 요소의 중간 위치로 이동 | |
move_to_element_with_offset(to_element, xoffset, yoffset) | 마우스를 해당 요소에서 offset만큼 이동한 위치로 이동 | |
pause(seconds) | 주어진 시간(초 단위)만큼 입력을 중지 | |
perform() | 이미 쌓여 있는(stored) 모든 행동을 수행(chaining) | |
reset_actions() | 이미 쌓여 있는(stored) 모든 행동을 제거 | |
send_keys(*keys_to_send) | 키보드 입력을 현재 focused된 요소에 보냄 | |
send_keys_to_element(element, *keys_to_send) | 키보드 입력을 주어진 요소에 보냄 | |
WebDriverWait | until(method, message='') | 특정 조건 충족 시까지 기다림 |
until_not(method, message='') | 특정 조건 충족되지 않을 시까지 기다림 | |
expected_conditions | presence_of_element_located(locator) | 요소가 DOM에 존재하는지 확인 |
visibility_of_element_located(locator) | 요소가 표시되는지 확인 | |
element_to_be_clickable(locator) | 요소가 클릭 가능한 상태인지 확인 | |
text_to_be_present_in_element(locator, text) | 특정 텍스트가 요소에 존재하는지 확인 | |
title_is(title) | 페이지 타이틀이 특정 값과 일치하는지 확인 | |
title_contains(text) | 페이지 타이틀이 특정 텍스트를 포함하는지 확인 | |
alert_is_present() | 알림 창이 나타났는지 확인 |
9. webdriver 클래스
- 웹 브라우저를 제어하기 위한 주요 클래스이다.
1) get(url)
- 기능: 지정된 URL로 이동한다.
- 사용 방법:
from selenium import webdriver
driver = webdriver.Chrome() # Chrome 브라우저 열기
driver.get("https://www.example.com") # 해당 URL로 이동
2) close()
- 기능: 현재 열린 브라우저 탭을 닫는다.
- 사용 방법:
driver.close() # 현재 탭 닫기
3) quit()
- 기능: 모든 브라우저 탭을 닫고 WebDriver 세션을 종료한다.
- 사용 방법:
driver.quit() # 브라우저 종료
4) 탭 생성, 갯수 확인, 이동, 닫기
1. 탭(새 창) 생성하기
- Selenium은 직접적으로 “새 탭 열기”를 위한 전용 메소드를 제공하지 않지만, JavaScript를 실행하여 새 탭을 열 수 있다.
- 예를 들어, 아래 코드는 새 탭을 열고 해당 탭에서 특정 URL을 로드하는 방법이다
- driver.execute_script("window.open('https://www.google.com', '_blank');")
- 이 명령은 브라우저에서 새 탭을 열고, 지정한 URL(여기서는 구글)을 로드한다.
- '_blank'는 새 탭이나 새 창에서 열리게 하는 표준 속성이다.
from selenium import webdriver
import time
# WebDriver 생성 (예: Chrome)
driver = webdriver.Chrome()
# 기존 탭에서 기본 URL 접속
driver.get("https://www.example.com")
# JavaScript를 사용하여 새 탭 열기
driver.execute_script("window.open('https://www.google.com', '_blank');")
# 새 탭이 열리는 시간을 약간 대기 (필요시)
time.sleep(2)
2. 탭(창)의 갯수 확인하기
- Selenium은 현재 브라우저에서 열려 있는 모든 창(탭)의 핸들(handle)을 driver.window_handles 속성을 통해 리스트로 제공한다.
- driver.window_handles는 문자열 형태의 식별자(handle)를 포함한 리스트이다.
- 이 리스트의 길이를 구하면 현재 열려 있는 탭(창)의 갯수를 알 수 있다.
# 현재 열려 있는 탭(창)의 핸들 리스트
handles = driver.window_handles
print("열려 있는 탭 갯수:", len(handles))
3. 특정 탭(창)으로 이동하기
- 탭 간 전환은 driver.switch_to.window(window_handle) 메소드를 사용한다.
예를 들어, 위에서 생성한 새 탭(구글)이 리스트의 두 번째 요소에 있다면 다음과 같이 전환할 수 있다
- driver.window_handles에서 원하는 탭의 인덱스를 선택하여 그 값을 사용한다.
- 기본적으로 첫 번째 탭은 인덱스 0에 해당한다.
# 예시: 두 번째 탭(새로 연 탭)으로 전환
handles = driver.window_handles
driver.switch_to.window(handles[1])
# 이제 현재 포커스는 새 탭(구글)으로 이동했으므로, 이후 작업은 새 탭에서 진행됨
print("현재 탭의 제목:", driver.title)
4. 탭(창) 닫기
- 현재 활성화된 탭(창)을 닫으려면 driver.close()를 사용한다.
- 예를 들어, 새 탭에서 작업을 완료한 후 해당 탭을 닫고, 이전 탭으로 돌아가려면 다음과 같이 한다.
- driver.close()는 현재 활성화된 탭(창)을 닫습니다.
- 탭을 닫은 후에는 포커스가 남아 있는 다른 창으로 이동하지 않으므로, 반드시 driver.switch_to.window()를 통해 원하는 창으로 전환해야 한다.
# 현재 활성 탭(예: 새 탭) 닫기
driver.close()
# 닫은 후에는 여전히 다른 탭(창)이 열려 있으므로,
# 명시적으로 원하는 탭으로 전환해야 함.
# 예를 들어, 첫 번째 탭으로 전환:
handles = driver.window_handles
driver.switch_to.window(handles[0])
print("이제 첫 번째 탭으로 전환되었습니다. 현재 탭의 제목:", driver.title)
5. 주의사항
- 탭 전환 후 작업:
- 탭(창)을 닫거나 전환할 때, Selenium은 현재 포커스가 있는 창에서 명령을 실행한다.
- 따라서 올바른 탭으로 전환한 후 작업을 수행해야 한다.
- 탭 닫은 후 핸들 재확인:
- 탭을 닫으면 driver.window_handles에 해당 핸들이 더 이상 포함되지 않으므로, 창을 닫은 후에는 새로이 핸들 리스트를 가져오는 것이 좋다.
- 브라우저 및 드라이버 버전:
- 사용 중인 브라우저와 WebDriver의 버전이 호환되어야 하며, 경우에 따라 새로운 탭이 아닌 새 창으로 열릴 수 있는 점도 참고해야 한다.
5) find_element(by, value)
- 기능: 단일 웹 요소를 찾는다.
- 사용 방법:
from selenium.webdriver.common.by import By
element = driver.find_element(By.ID, "username") # ID로 요소 찾기
6) find_elements(by, value)
- 기능: 여러 웹 요소를 리스트로 반환한다.
- 사용 방법:
elements = driver.find_elements(By.CLASS_NAME, "menu-item") # 클래스 이름으로 여러 요소 찾기
7) get_cookies()
- 기능: 현재 세션의 모든 쿠키를 반환한다.
- 사용 방법:
cookies = driver.get_cookies() # 쿠키 가져오기
print(cookies)
8) add_cookie(cookie_dict)
- 기능: 쿠키를 추가한다.
- 사용 방법:
driver.add_cookie({"name": "session", "value": "12345"}) # 쿠키 추가
9) delete_cookie(name)
- 기능: 특정 이름의 쿠키를 삭제한다.
- 사용 방법:
driver.delete_cookie("session") # 쿠키 삭제
10) delete_all_cookies()
- 기능: 모든 쿠키를 삭제한다.
- 사용 방법:
driver.delete_all_cookies() # 모든 쿠키 삭제
11) execute_script(script, *args)
- 기능: JavaScript 코드를 실행한다.
- 사용 방법:
# 화면 스크롤 하단 이동 (하단 끝까지 이동)
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);") # 페이지 스크롤
# 화면 스크롤 상단 이동
driver.execute_script('window.scrollTo(0, 0);')
12) save_screenshot(filename)
- 기능: 현재 화면을 스크린샷으로 저장한다.
- 사용 방법:
driver.save_screenshot("screenshot.png") # 스크린샷 저장
10. WebElement 클래스
- 웹 페이지의 요소를 제어하기 위한 클래스이다.
1) click()
- 기능: 요소를 클릭한다.
- 사용 방법:
element = driver.find_element(By.ID, "submit-button")
element.click() # 요소 클릭
2) send_keys(*value)
- 기능: 요소에 텍스트를 입력한다.
- 사용 방법:
element = driver.find_element(By.ID, "username")
element.send_keys("user123") # 텍스트 입력
- 파일 업로드
- 파일을 받는 <input>을 선택한 뒤, send_keys(file_path)를 호출하면 된다.
upload = driver.find_element(By.TAG_NAME, 'input')
# 이전 버전
# upload = driver.find_element_by_tag('input')
upload.send_keys(file_path)
- 입력할 수 있는 KEY 목록
class Keys(object):
"""
Set of special keys codes.
"""
NULL = '\ue000'
CANCEL = '\ue001' # ^break
HELP = '\ue002'
BACKSPACE = '\ue003'
BACK_SPACE = BACKSPACE
TAB = '\ue004'
CLEAR = '\ue005'
RETURN = '\ue006'
ENTER = '\ue007'
SHIFT = '\ue008'
LEFT_SHIFT = SHIFT
CONTROL = '\ue009'
LEFT_CONTROL = CONTROL
ALT = '\ue00a'
LEFT_ALT = ALT
PAUSE = '\ue00b'
ESCAPE = '\ue00c'
SPACE = '\ue00d'
PAGE_UP = '\ue00e'
PAGE_DOWN = '\ue00f'
END = '\ue010'
HOME = '\ue011'
LEFT = '\ue012'
ARROW_LEFT = LEFT
UP = '\ue013'
ARROW_UP = UP
RIGHT = '\ue014'
ARROW_RIGHT = RIGHT
DOWN = '\ue015'
ARROW_DOWN = DOWN
INSERT = '\ue016'
DELETE = '\ue017'
SEMICOLON = '\ue018'
EQUALS = '\ue019'
NUMPAD0 = '\ue01a' # number pad keys
NUMPAD1 = '\ue01b'
NUMPAD2 = '\ue01c'
NUMPAD3 = '\ue01d'
NUMPAD4 = '\ue01e'
NUMPAD5 = '\ue01f'
NUMPAD6 = '\ue020'
NUMPAD7 = '\ue021'
NUMPAD8 = '\ue022'
NUMPAD9 = '\ue023'
MULTIPLY = '\ue024'
ADD = '\ue025'
SEPARATOR = '\ue026'
SUBTRACT = '\ue027'
DECIMAL = '\ue028'
DIVIDE = '\ue029'
F1 = '\ue031' # function keys
F2 = '\ue032'
F3 = '\ue033'
F4 = '\ue034'
F5 = '\ue035'
F6 = '\ue036'
F7 = '\ue037'
F8 = '\ue038'
F9 = '\ue039'
F10 = '\ue03a'
F11 = '\ue03b'
F12 = '\ue03c'
META = '\ue03d'
COMMAND = '\ue03d'
3) clear()
- 기능: 요소의 텍스트를 지운다.
- 사용 방법:
element = driver.find_element(By.ID, "username")
element.clear() # 텍스트 지우기
4) get_attribute(name)
- 기능: 요소의 속성 값을 반환한다.
- 사용 방법:
element = driver.find_element(By.ID, "username")
value = element.get_attribute("value") # 속성 값 가져오기
print(value)
5) is_displayed()
- 기능: 요소가 화면에 표시되는지 확인한다.
- 사용 방법:
element = driver.find_element(By.ID, "username")
print(element.is_displayed()) # 요소가 표시되는지 확인
6) is_enabled()
- 기능: 요소가 활성화되어 있는지 확인한다.
- 사용 방법:
element = driver.find_element(By.ID, "submit-button")
print(element.is_enabled()) # 요소가 활성화되었는지 확인
7) is_selected()
- 기능: 요소가 선택되었는지 확인한다 (체크박스, 라디오 버튼 등).
- 사용 방법:
element = driver.find_element(By.ID, "agree-checkbox")
print(element.is_selected()) # 요소가 선택되었는지 확인
11. By 클래스
- 요소를 찾기 위한 선택자이다.
1) ID
- 기능: ID로 요소를 찾는다.
- 사용 방법:
element = driver.find_element(By.ID, "username")
2) NAME
- 기능: Name 속성으로 요소를 찾는다.
- 사용 방법:
element = driver.find_element(By.NAME, "username")
3) CLASS_NAME
- 기능: 클래스 이름으로 요소를 찾는다.
- 사용 방법:
element = driver.find_element(By.CLASS_NAME, "menu-item")
4) TAG_NAME
- 기능: 태그 이름으로 요소를 찾는다.
- 사용 방법:
element = driver.find_element(By.TAG_NAME, "div")
5) CSS_SELECTOR
- 기능: CSS 선택자로 요소를 찾는다.
- 사용 방법:
element = driver.find_element(By.CSS_SELECTOR, "div.menu-item")
6) XPATH
- 기능: XPath로 요소를 찾는다.
- 사용 방법:
element = driver.find_element(By.XPATH, "//div[@class='menu-item']")
12. Keys 클래스
키보드 입력을 위한 클래스이다.
1) RETURN
- 기능: Enter 키를 입력한다.
- 사용 방법:
from selenium.webdriver.common.keys import Keys
element = driver.find_element(By.ID, "username")
element.send_keys(Keys.RETURN) # Enter 키 입력
2) ENTER
- 기능: Enter 키를 입력한다 (RETURN과 동일).
- 사용 방법:
element.send_keys(Keys.ENTER)
3) TAB
- 기능: Tab 키를 입력한다.
- 사용 방법:
element.send_keys(Keys.TAB) # Tab 키 입력
13. ActionChains 클래스
- 복합적인 동작을 수행하기 위한 클래스이다.
1) click(on_element=None)
- 기능: 요소를 클릭한다.
- 사용 방법:
from selenium.webdriver.common.action_chains import ActionChains
element = driver.find_element(By.ID, "submit-button")
actions = ActionChains(driver)
actions.click(element).perform() # 요소 클릭
2) double_click(on_element=None)
- 기능: 요소를 더블 클릭한다.
- 사용 방법:
actions.double_click(element).perform() # 더블 클릭
3) context_click(on_element=None)
- 기능: 요소를 우클릭한다.
- 사용 방법:
actions.context_click(element).perform() # 우클릭
4) move_to_element(to_element)
- 기능: 요소 위로 마우스를 이동한다.
- 사용 방법:
actions.move_to_element(element).perform() # 마우스 이동
- 화면 스크롤 특정 태그 지점까지 이동
from selenium.webdriver import ActionChains
# 타겟 정의
some_tag = driver.find_element(By.CSS_SELECTOR, value="#content > div.cover-list > div > ul > li:nth-child(1) > a")
# actioncahins 생성
action = ActionChains(driver)
# 실행
action.move_to_element(some_tag).perform()
5) drag_and_drop(source, target)
- 기능: 요소를 드래그하여 다른 위치로 이동한다.
- 사용 방법:
source = driver.find_element(By.ID, "source")
target = driver.find_element(By.ID, "target")
actions.drag_and_drop(source, target).perform() # 드래그 앤 드롭
6) perform()
- 기능: 액션을 실행한다.
- 사용 방법: 위 예제 참조.
14. WebDriverWait 클래스
- 명시적 대기를 위한 클래스이다.
1) until(method, message='')
- 기능: 조건이 충족될 때까지 대기한다.
- 사용 방법:
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.ID, "username"))
) # 요소가 나타날 때까지 최대 10초 대기
2) until_not(method, message='')
- 기능: 조건이 충족되지 않을 때까지 대기한다.
- 사용 방법:
WebDriverWait(driver, 10).until_not(
EC.text_to_be_present_in_element((By.ID, "status"), "Loading")
) # "Loading" 텍스트가 사라질 때까지 대기
15. expected_conditions 클래스
- 조건을 정의하는 클래스이다.
1) presence_of_element_located(locator)
- 기능: 요소가 DOM에 존재하는지 확인한다.
- 사용 방법: 위 예제 참조.
2) visibility_of_element_located(locator)
- 기능: 요소가 화면에 표시되는지 확인한다.
- 사용 방법:
element = WebDriverWait(driver, 10).until(
EC.visibility_of_element_located((By.ID, "username"))
)
3) element_to_be_clickable(locator)
- 기능: 요소가 클릭 가능한지 확인한다.
- 사용 방법:
element = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.ID, "submit-button"))
)
4) text_to_be_present_in_element(locator, text)
- 기능: 요소에 특정 텍스트가 포함되어 있는지 확인한다.
- 사용 방법:
WebDriverWait(driver, 10).until(
EC.text_to_be_present_in_element((By.ID, "status"), "Complete")
)
16. Selenium 4에서 변경된 주요 사항들 정리
1) W3C WebDriver 표준 준수
- 변경 사항: Selenium 4는 W3C WebDriver 표준을 완전히 준수한다.
- 영향:
- 이전 버전에서는 JSON Wire Protocol을 사용했지만, Selenium 4부터는 W3C 표준 프로토콜을 사용한다.
- 브라우저와의 상호작용이 더 안정적이고 표준화되었다.
- 브라우저별로 동작이 달라지는 문제가 줄어들었다.
2) Relative Locators (상대적 위치 기반 요소 찾기)
- 새로운 기능: 요소를 상대적인 위치로 찾을 수 있는 새로운 로케이터가 추가되었다.
- 사용 예시:
- above(), below(), toLeftOf(), toRightOf(), near() 메서드를 사용해 다른 요소를 기준으로 위치한 요소를 찾는다.
from selenium.webdriver.common.by import By
from selenium.webdriver.support.relative_locator import locate_with
password_field = driver.find_element(By.ID, "password")
email_field = driver.find_element(locate_with(By.TAG_NAME, "input").above(password_field))
3) Chrome DevTools Protocol (CDP) 통합
- 새로운 기능: Chrome DevTools Protocol을 직접 사용할 수 있다.
- 사용 예시:
- 네트워크 요청 모니터링, 성능 측정, 캐시 제어 등 브라우저의 내부 동작을 세부적으로 제어할 수 있다.
from selenium.webdriver import Chrome
from selenium.webdriver.common.devtools.v94 import network
driver = Chrome()
driver.execute_cdp_cmd('Network.enable', {})
driver.execute_cdp_cmd('Network.setCacheDisabled', {'cacheDisabled': True})
4) 새로운 Window 및 Tab 관리 API
- 변경 사항: 새로운 Window 및 Tab 관리 API가 추가되었다.
- 사용 예시:
- driver.switch_to.new_window('tab') 또는 driver.switch_to.new_window('window')를 사용하여 새 탭이나 창을 열 수 있다.
driver.switch_to.new_window('tab') # 새 탭 열기
driver.switch_to.new_window('window') # 새 창 열기
5) 개선된 로깅 기능
- 새로운 기능: 브라우저 로그 및 성능 로그를 더 쉽게 수집할 수 있다.
- 사용 예시:
- driver.get_log('browser')를 사용하여 브라우저 로그를 가져올 수 있다.
logs = driver.get_log('browser')
for log in logs:
print(log)
6) 개선된 요소 스크린샷 기능
- 새로운 기능: 특정 요소만 스크린샷을 찍을 수 있다.
- 사용 예시:
element = driver.find_element(By.ID, "element-id")
element.screenshot("element_screenshot.png")
7) 업데이트된 Actions 클래스
- 변경 사항: Actions 클래스가 개선되어 더 직관적이고 강력해졌다.
- 사용 예시:
- pause(), scroll_to_element() 등의 새로운 메서드가 추가되었다.
from selenium.webdriver.common.action_chains import ActionChains
actions = ActionChains(driver)
actions.scroll_to_element(element).perform()
8) find_element와 find_elements의 통합
- 변경 사항: find_element_by_* 메서드가 제거되고, find_element(By.*, value) 방식으로 통합되었다.
- 사용 예시:
- `find_element`류 함수들의 사용법이 함수명에 `by_xxx`를 쓰는 대신
`By.XXX` 인자를 주는 것으로 바뀌었다.
# 이전 버전에서는 아래와 같이 쓴다.
search_box = driver.find_element_by_xpath('//*[@id="tsf"]/div[2]/div[1]/div[1]/div/div[2]/input')
# selenium 4 이상에서는 By.XXX를 인자로 준다.
search_box = driver.find_element(By.XPATH, '//*[@id="tsf"]/div[2]/div[1]/div[1]/div/div[2]/input')
from selenium.webdriver.common.by import By
element = driver.find_element(By.ID, "element-id")
elements = driver.find_elements(By.CLASS_NAME, "class-name")
9) 개선된 Grid 기능
- 새로운 기능: Selenium Grid 4가 도입되었으며, Kubernetes와의 통합, Docker 지원 등이 강화되었다.
- 주요 변경 사항:
- 더 빠르고 안정적인 분산 테스트 환경 제공
- 동적 그리드 구성 지원
- 모니터링 및 관리 기능 강화
10) timeouts 설정 방식 변경
- 변경 사항: timeouts 설정 방식이 더 직관적으로 변경되었다.
- 사용 예시:
driver.set_page_load_timeout(30) # 페이지 로드 타임아웃 설정
driver.set_script_timeout(20) # 스크립트 실행 타임아웃 설정
driver.implicitly_wait(10) # 암시적 대기 시간 설정
11) print 기능 지원
- 새로운 기능: 페이지를 PDF로 저장할 수 있는 기능이 추가되었습니다.
- 사용 예시:
from selenium.webdriver.common.print_page_options import PrintOptions
print_options = PrintOptions()
print_options.page_ranges = ['1-2']
driver.print_page(print_options)
12) BiDi (Bi-Directional) API 지원
- 새로운 기능: 브라우저와 양방향 통신을 지원하는 BiDi API가 추가되었다.
- 사용 예시:
- 브라우저 이벤트를 실시간으로 모니터링하거나, 브라우저에 명령을 전달할 수 있다.
13) WebDriverManager와의 통합
- 새로운 기능: WebDriverManager를 사용하여 브라우저 드라이버를 자동으로 관리할 수 있다.
- 사용 예시:
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver import Chrome
driver = Chrome(ChromeDriverManager().install())
14) executable_path 인자 폐기
- 더 이상 webdriver.chrome()에 executable_path를 사용하지 않는다.
# 이전버전
driver = webdriver.Chrome(executable_path=’chromedriver’)
# 4 이상
driver = webdriver.Chrome()
- reference :
Python, Machine & Deep Learning
Python, Machine Learning & Deep Learning
greeksharifa.github.io
[제로베이스] Selenium 정리
beatuful soup 에서는 xpath 를 사용할 수 없다.//\*@id="main_pack"/section1/div/div2/panel-list/div/ul/li2/div/div/a// : 최상위: 자손 태그/ : 자식 태그div1 : div 중에서 1번째 태그브
velog.io
셀레니움Selenium 주요 기능 모음, 주로 쓰는 메소드 모음
셀레니움 주요 클래스별 메소드 ✔️ webdriver: 브라우저 제어 클래스.브라우저 인스턴스를 생성하고 제어함. webdriver.Chrome(), webdriver.Firefox(), webdriver.Safari(), webdriver.Edge(): 브라우저 설정.get(url):
sy-log.tistory.com
https://www.selenium.dev/documentation/
The Selenium Browser Automation Project
Selenium is an umbrella project for a range of tools and libraries that enable and support the automation of web browsers. It provides extensions to emulate user interaction with browsers, a distribution server for scaling browser allocation, and the infra
www.selenium.dev
SeleniumBase Docs
SeleniumBase All-in-one Browser Automation Framework:Web Crawling / Testing / Scraping / Stealth 🚀 Start | 🏰 Features | 🎛️ Options | 📚 Examples | 🌠 Scripts | 📱 Mobile 📘 APIs | 🔠 Formats | 🔴 Recorder | 📊 Dashboard | 🗾 Loca
seleniumbase.io
'Crawling' 카테고리의 다른 글
BeautifulSoup4 매뉴얼 정리 (0) | 2025.02.06 |
---|---|
requests 라이브러리 기본 메뉴얼 정리 (0) | 2025.02.06 |
댓글