🔎 selenium로 마우스, 키보드 이벤트를 처리해 특정 사이트 로그인을 해 보자
- 요즈음은
간편 로그인
이라는 기능을 지원하는 서비스가 많다.
- 이때 바로 해당 링크로 접속하는 게 아니라 플랫폼에서 로그인을 해야 하는 경우가 많다.
selenium
을 통해 자동 로그인
이 가능하게 할 수 있다.
naver
나 daum
같은 포털 사이트
는 이렇게 해도 로그인
이 되지는 않고, 2차 인증
이 필요하다.
1. 로그인을 위해 필요한 라이브러리 호출
- 로그인을 위해
selenium
의 webdriver
를 사용해 줄 것이기 때문에 일단 이 라이브러리를 호출한다.
- 우리는 크롬을 사용할 것이기 때문에
ChromeDriverManager
역시 호출해 준다.
마우스 이벤트
와 키보드 이벤트
를 통해 Action
을 취할 것이기 때문에 ActionBuilder
와 Keys
, ActionChains
도 호출해야 한다.
- 또한 특정 요소를 찾아야 하기 때문에
.find_element
를 위한 By
라이브러리도 불러와 주어야 한다.
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
2. 로그인 할 사이트의 요청 보내기
ChromeDriverManager
를 사용해 준다.
get
을 통해 가지고 온 응답을 바로 읽지 않고 Implicitly Wait
를 적용해 준다.
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))
driver.get("https://www.naver.com/")
driver.implicitly_wait(0.5)
3. 웹 페이지에서 로그인 버튼의 위치 확인
- 웹 페이지에서
로그인 버튼
을 우 클릭 후 검사
를 누르면 HTML
에서의 로그인 버튼
의 위치를 알 수 있다.
로그인 버튼
을 지칭하기 위해서는 어떤 요소가 가장 적합한지 확인하는데 현재 로그인 버튼
은 ID
가 따로 존재하지 않고 class
가 존재하므로 class name
을 이용해 호출해야 한다는 것을 파악한다.
로그인 버튼
을 click
해야 하므로 필요한 이벤트가 click
임을 알 수 있다.
4. 로그인 버튼 클릭 구현
- 3번의 과정을 통해
로그인 버튼
의 class name
이 link_login
임을 알 수 있다.
- 종종
class
의 이름이 두 개 이상인 경우도 있는데 이는 class의 계층 구조
라고 생각하면 된다. 이 경우 호출할 때는 앞의 클래스명.뒤의 클래스명
으로 호출해 준다.
.find_element
로 button
을 찾아 준다.
- 어떠한 이벤트(Action)을 취할 때는
ActionChains
을 통해 연쇄적으로 진행할 수 있게 해 준다. ActionChains
의 끝에는 .perform()
이 있어야 해당 이벤트를 수행할 수 있다.
button = driver.find_element(By.CLASS_NAME, "link_login")
ActionChains(driver).click(button).perform()
5. 로그인 창 분석
- 버튼을 누른 후 나오는
로그인 창
을 분석한다.
로그인 창
은 다음과 같이 아이디 입력 칸
, 비밀번호 입력 칸
, 로그인 버튼
이 로그인을 하기 위해 정보임을 알 수 있다.
ID
는 고유의 값이므로 ID
가 존재한다면 .find_element
를 사용할 때 target
을 ID
로 잡아 줘야 한다.
아이디 입력 칸의 ID
는 id
이고, 비밀번호 입력 칸의 ID
는 pw
, 로그인 버튼의 ID
는 log.login
이다.
6. 아이디와 비밀번호 입력하기
아이디 입력 칸
과 비밀번호 입력 칸
은 키보드 이벤트
를 적용시켜야 한다.
- 먼저 로그인 화면으로 이동하는 버튼을 찾아 준 것과 동일하게
.find_element
를 통해 각 input 칸
을 찾아 준다.
- 이후
.send_keys_to_element(target, 입력해 줄 값)
의 이벤트를 취한다.
- 이때 이벤트들을 연쇄적으로 진행되게 해 주기 위해
ActionChains
을 사용한다.
id_input = driver.find_element(By.ID, "id")
ActionChains(driver).send_keys_to_element(id_input, "각자의 아이디").perform()
password_input = driver.find_element(By.ID, "pw")
ActionChains(driver).send_keys_to_element(password_input, "각자의 비밀번호").perform()
7. 로그인 버튼 클릭
login_button = driver.find_element(By.ID, "log.login")
ActionChains(driver).click(login_button).perform()
8. time.sleep 주기
- 이러한 과정이 일련으로 빠르게 일어나다 보면 이벤트 중 하나가 제대로 동작하지 않거나 하는 문제가 발생할 수 있다.
- 그러므로
time
라이브러리를 추가해 주어서 time.sleep(초)
를 통해 모션
사이의 임의의 시간
을 부여한다.
최종 코드
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
import time
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))
driver.get("https://www.naver.com/")
driver.implicitly_wait(0.5)
button = driver.find_element(By.CLASS_NAME, "link_login")
ActionChains(driver).click(button).perform()
id_input = driver.find_element(By.ID, "id")
ActionChains(driver).send_keys_to_element(id_input, "각자의 아이디").perform()
time.sleep(1)
password_input = driver.find_element(By.ID, "pw")
ActionChains(driver).send_keys_to_element(password_input, "각자의 비밀번호").perform()
time.sleep(1)
login_button = driver.find_element(By.ID, "log.login")
ActionChains(driver).click(login_button).perform()
time.sleep(1)