Selenium

안재영·2024년 4월 4일

Selenium

셀레니움은 프로그램을 이용해 자동화된 웹 테스트를 수행할 수 있도록 해주는 프레임워크이다.

셀레니움과 웹 드라이버를 이용하면 파이썬에서 웹 브라우저를 제어하여 컨트롤 할 수 있습니다

셀레니움 사용법

셀레니움과 웹 드라이버를 사용하기 위해선 일단 라이브러리 인스톨 과정이 필요합니다

pip install Selenium
pip install webdriver-manager

설치가 완료됬으면 셀레니움을 사용해봅시다

from selenium import webdriver        <- 웹 브라우저와 연결
from selenium.webdriver.chrome.service import Service <- 크롬 객체생성시 필요
from webdriver_manager.chrome import ChromeDriverManager <- 크롬과 싱크를 맞추기위해 사용

필요한 라이브러리들을 import시켜줍니다

driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))

위 코드를 실행시키면 크롬 브라우저가 열립니다

하지만 그냥 브라우저가 열릴 뿐 평소에 열던 브라우저처럼 구글이 보이지않을 뿐만아니라 아무것도 보이지 않습니다

이제 드라이버를 이용해 주소를 여는법을 알아봅시다

driver.get("http://www.naver.com")

get을 이용하니 브라우저가 네이버로 이동하는것을 확인할수 있습니다

이번에는 켜져있는 페이지에서 화면을 html로 받아와봅시다

print(driver.page_source)

페이지 소스가 출력되는것을 확인 할 수 있습니다

작업이 끝났지만 브라우저는 그대로 켜져있습니다

이번에는 위 동작을 완료하면 창이 꺼지도록 해봅시다

with webdriver.Chrome(service=Service(ChromeDriverManager().install())) as driver :
    driver.get("http://www.example.com")
    print(driver.page_source)

with as 구문을 사용하면 동작을 완료한후 자동으로 브라우저가 종료되는것을 확인할수 있습니다

이번에는 소스가 아닌 특정 태그의 text를 가져오는 방법을 알아봅시다

from selenium.webdriver.common.by import By

with webdriver.Chrome(service=Service(ChromeDriverManager().install())) as driver :
    driver.get("http://www.example.com")
		print(driver.find_element(By.TAG_NAME, "p").text)

example 페이지에서 볼수있는 첫번째 p 태그를 가져와서 내용을 출력하는것을 볼수있습니다

하나의 요소를 찾을때는 셀레니움에 By를 import 시킨후

.find_element(by, target) 를 이용하면 해당 요소를 찾을수있습니다

.find_element(By.기준, target)

  • 기준 : ID, TAG_NAME, CLASS_NAME 등등

여러개의 요소를 가져오는방법또한 크게 다르지않습니다

with webdriver.Chrome(service=Service(ChromeDriverManager().install())) as driver :
    driver.get("http://www.example.com")
    for el in driver.find_elements(By.TAG_NAME, "p") :
        print(el.text)

하지만 list형태로 받아오기 때문에 for문을 사용해서 출력합니다

Xpath란?

Xpath 는 XML, HTML 문서 등의 요소의 위치를 경로로 표현하는 것을 의미합니다.

웹 페이지에서 원하는 데이터의 class나 id를 특정 할 수 없을 경우

웹 페이지의 구조를 이해한 뒤 Xpath를 이용해서 원하는 데이터를 가져올 수 도 있습니다

Xpath 예시

/html/body/div/h1

비동기적 페이지에서는 원하는 정보의 위치를 특정하여 가져오고 싶어도 페이지 자체에 데이터가 도착하지않아 가져올수 없는경우가 발생할수 있습니다 이러한 경우는 wait를 이용하여 해결합니다

wait & call

Implicit / Explicit Wait

  • Implicit Wait :정해진 시간만큼 대기

    implicitly_wait()

    from selenium.webdriver.support.ui import WebDriverWait
    
    driver.implicitly_wait(20)

주의할 점으론 입력한 시간을 반드시 기다리는것이 아닌 로딩을 기다리는 한계 시간을 의미하고있습니다

  • Explicit Wait : 조건이 성립될때까지 대기

    WebDriverWait()

  from selenium.webdriver.support import expected_conditionsas EC

  element = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "target")))

id가 target인 요소가 존재할 때까지 기다린 후 다음 명령을 진행하는 코드입니다

until() 이 아닌 until_not()을 사용한다면 해당인자가 만족되지 않을때 까지 기다리는 코드로 변경할수 있습니다

Xpath와 wait를 이용하면 비동기페이지에 대해서도 정보를 가져올수 있지만 해당방법은 결국 같은 구조를 가지지않은 페이지에서는 사용할수 없기때문에 주의해야됩니다

Mouse Event & keyboard Event

  • mouse Event의 대표적인 event
    • move - 마우스 이동
    • press down - 마우스 누르기
    • press up - 마우스 때기
    • click - 클릭
button = driver.find_element(By.ID, "button")
ActionChains(driver).click(button).perform()

ActionChains 를 이용하면 동작을 연속적으로 실행시켜줄수 있습니다

ActionChains와 perform사이에 동작들을 채워넣으면 그 사이의 동작들을 연쇄적으로 작동시킬수 있습니다

마우스 이벤트와 키보드 이벤트를 이용하여 네이버 로그인을 해봅시다

from selenium import webdriver
from selenium.webdriver import ActionChains
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver import Keys, ActionChains
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By

driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))
driver.get("https://www.naver.com")
driver.implicitly_wait(3)

button = driver.find_element(By.CLASS_NAME, "MyView-module__my_login___tOTgr")
ActionChains(driver).click(button).perform()

성공적으로 이동하는것을 확인할수 있습니다

로그인 페이지로 이동했으면 이제 정보를 입력해야합니다

이번에는 아이디를 입력해봅시다

id_input = driver.find_element(By.ID, "id")

ActionChains(driver).send_keys_to_element(id_input, "아이디").perform()

send_keys_to_element(요소, “값”)을 이용하면 정보를 요소로 보낼수있습니다

이번에는 비밀번호를 입력해봅시다

pw_input = driver.find_element(By.ID, "pw")

ActionChains(driver).send_keys_to_element(pw_input, "비밀번호").perform()

입력을 완료했으면 로그인 버튼을 눌러줍시다

login_button = driver.find_element(By.ID, "log.login")

ActionChains(driver).click(login_button).perform()

정상적으로 로그인버튼까지 눌러졌습니다

하지만 이러한 액션들이 너무 빠르게 전환 되다 보면 웹 상에서의 이벤트가 작동하다가 오류가 발생 할 수 있습니다

이러한 문제를 해결하는 가장 간단한 방법인 행동 사이사이에 딜레이를 주는방법이 있습니다

행동 사이사이에 딜레이를 주는예시

import time

id_input = driver.find_element(By.ID, "id")
ActionChains(driver).send_keys_to_element(id_input, "아이디").perform()
time.sleep(1)

pw_input = driver.find_element(By.ID, "pw")
ActionChains(driver).send_keys_to_element(pw_input, "비밀번호").perform()
time.sleep(1)

login_button = driver.find_element(By.ID, "log.login")
ActionChains(driver).click(login_button).perform()

0개의 댓글