[4/4] TIL - Selenium

Sangwon Jwa·2024년 4월 4일

데브코스 TIL

목록 보기
9/54
post-thumbnail

📖 학습 주제


  1. Selenium
  2. Wait and Call
  3. 마우스 이벤트 처리하기
  4. 키보드 이벤트 처리하기

✏️ 주요 메모 사항 소개


Selenium

파이썬을 사용해서 웹 브라우저를 조작할 수 있는 자동화 프레임워크. 마우스나 키보드를 이용한 조작을 파이썬으로 수행할 수 있다. 추가로
웹 브라우저와 연동을 하고 제어하기 위해 Web Driver가 필요하다.

설치

pip install selenium
pip install webdriver-manager

Import

# selenium으로부터 webdriver 모듈을 불러옵니다.

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager

웹 페이지 연동하기

# Chrome() 객체 생성
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))

# get 메서드를 통해 요청을 보냄
driver.get("http://www.example.com")

# page_source 속성을 통해 HTML 문서확인하기
print(driver.page_source)
  • 프로그램을 실행 시키면 Chrome 창이 계속 켜져있게 된다. with-as 구문을 사용하면 명령이 끝났을 때 driver 를 종료하도록 설정 가능
with webdriver.Chrome(service=Service(ChromeDriverManager().install())) as driver:
    driver.get("https://www.example.com")
    print(driver.page_source)

Driver에서 특정 요소 추출하기

  • .find_element(by,target) : 요소 하나 찾기
  • .find_elements(by,target) : 요소 여러개 찾기
  • by : 대상을 찾는 기준 EX) ID, TAG-NAME, CLASS_NAME ...
  • target : 대상의 속성
# 요소 한개 추출
# 기준을 설정할 By 라이브러리 import
from selenium.webdriver.common.by import By

# url 연결 후 p 태그로 이루어진 요소 하나 추출
with webdriver.Chrome(service=Service(ChromeDriverManager().install())) as driver:
    driver.get("https://www.example.com")
    print(driver.find_element(By.TAG_NAME, "p").text)
# 요소 여러개 추출
with webdriver.Chrome(service=Service(ChromeDriverManager().install())) as driver:
    driver.get("https://www.example.com")
    # find_elements는 리스트 형태로 반환, for 문을 통해 출력
    for element in driver.find_elements(By.TAG_NAME, "p"):
        print("Text : ", element.text)

Wait and Call

  • find 메서드를 사용해서 요소를 추출하다 보면 동적 웹페이지와 같은 경우 데이터가 전부 load 되기 전에 메서드를 실행해 결과값에 오류가 생기는 경우가 있다.
  • 따라서 적절하게 웹 페이지가 전부, 혹은 찾으려는 부분이 로딩 될 때 까지 기다렸다가 추출을 하는 방법이 필요하다.
  • Selenium 은 동적 웹 사이트에 대한 지원을 진행하기 위해 명시적 기다림(Explicit Wait)과 암묵적 기다림(Implicit Wait)을 지원함.
  1. 암묵적 기다림 (Implicit) : 다 로딩이 될 때까지 지정한 시간 동안 기다림.
  2. 명시적 기다림 (Explicit) : 특정 요소에 대한 제약을 통한 기다림. 찾으려는 요소가 가져올 수 있을 때까지 기다리기.

XPath

  • 스크래핑을 방지할 목적으로 랜덤하게 class 이름을 생성하는 웹 페이지들도 있음. 이 경우에 요소의 위치를 활용할 수 있다. XPathXML, HTML 문서 등의 요소의 위치를 경로로 표현하는 것을 의미한다.
# 라이브러리 import

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from webdriver_manager.chrome import ChromeDriverManager
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))
driver.get("https://indistreet.com/live?sortOption=startDate%3AASC")

# 요소를 XPATH를 이용한 위치로 찾기
driver.find_element(By.XPATH, '//*[@id="__next"]/div/main/div[2]/div/div[4]/div[1]/div[1]/div/a/div[2]/p[1]')

암묵적 기다림

# 10초동안 Implicit Wait을 진행하도록 해서 스크래핑이 잘 이루어지도록 수정해봅시다.
# 10초까지 기다리는데 완전한 응답이 온다면 다음걸로 넘어감.

from selenium.webdriver.support.ui import WebDriverWait


with webdriver.Chrome(service=Service(ChromeDriverManager().install())) as driver:
    driver.get("https://indistreet.com/live?sortOption=startDate%3AASC")
    
    # 로딩이 전부 완료될때까지의 한계 시간을 10초 설정
    driver.implicitly_wait(10)
    print(driver.find_element(By.XPATH, '//*[@id="__next"]/div/main/div[2]/div/div[4]/div[1]/div[1]/div/a/div[2]/p[1]').text)

명시적 기다림

from selenium.webdriver.support import expected_conditions as EC


with webdriver.Chrome(service=Service(ChromeDriverManager().install())) as driver:
    driver.get("https://indistreet.com/live?sortOption=startDate%3AASC")
    
    # Explicit Wait으로 변경, 
    element = WebDriverWait(driver,10).until(EC.presence_of_element_located((By.XPATH, '//*[@id="__next"]/div/main/div[2]/div/div[4]/div[1]/div[1]/div/a/div[2]/p[1]')))
    print(element.text)
    

실습 (여러 공연 제목 가져오기)

with webdriver.Chrome(service=Service(ChromeDriverManager().install())) as driver:
    driver.get("https://indistreet.com/live?sortOption=startDate%3AASC")
    driver.implicitly_wait(10)

    for i in range(1,11):
        element = driver.find_element(By.XPATH, '//*[@id="__next"]/div/main/div[2]/div/div[4]/div[1]/div[{}]/div/a/div[2]/p[1]'.format(i))
        print(element.text) 

마우스 이벤트 처리

웹 페이지에서 일어나는 일들을 Event라고 함. 마우스로 일어날 수 있는 대표적인 이벤트는 마우스 움직이기(move), 마우스 누르기(press down), 마우스 떼기(press up)등이 있다. 버튼을 찾은 후 이를 클릭하는 것을 구현하려면

  1. 입력하고자 하는 대상 요소 찾기 (find_element())
  2. 입력하고자 하는 내용을 click을 통해 전달.
  3. .perform()을 통해 동작

라이브러리 불러오기

from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from webdriver_manager.chrome import ChromeDriverManager

마우스 이벤트 실행

driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))
driver.get("https://hashcode.co.kr/")
driver.implicitly_wait(0.5)

# 로그인 버튼 찾기
button = driver.find_element(By.XPATH, '//*[@id="main-app-header"]/header/section/div/div/div/a[1]')

# 클릭 실행
ActionChains(driver).click(button).perform()

키보드 이벤트 처리

위의 마우스 이벤트 처리와 동일하게 키보드 이벤트 또한 같은 방식으로 처리한다. 다른 점은 send_keys_to_element 를 통해 입력하고자 하는 내용을 전달한다.

라이브러리 불러오기

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를 이용해 해당 사이트에 요청을 보내봅시다.
import time

# 웹페이지 연결
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))
driver.get("https://hashcode.co.kr")
time.sleep(1)

# 내비게이션 바에서 "로그인" 버튼을 찾아 눌러봅시다.
button = driver.find_element(By.XPATH, '//*[@id="main-app-header"]/header/section/div/div/div/a[1]')
ActionChains(driver).click(button).perform()
time.sleep(1)

# "아이디" input 요소에 여러분의 아이디를 입력합니다.
id_input = driver.find_element(By.XPATH, '//*[@id="main-app-account"]/div/div[2]/div/div[2]/div[1]/div/div[2]/div[2]/input')
ActionChains(driver).send_keys_to_element(id_input, "사용자 아이디").perform()
time.sleep(1)

# "패스워드" input 요소에 여러분의 비밀번호를 입력합니다.
pw_input = driver.find_element(By.XPATH, '//*[@id="main-app-account"]/div/div[2]/div/div[2]/div[1]/div/div[2]/div[4]/input')
ActionChains(driver).send_keys_to_element(pw_input, "사용자 비밀번호").perform()
time.sleep(1)

# "로그인" 버튼을 눌러서 로그인을 완료합니다.
login_button = driver.find_element(By.XPATH, '//*[@id="main-app-account"]/div/div[2]/div/div[2]/div[1]/div/div[2]/button')
ActionChains(driver).click(login_button).perform()
time.sleep(1)

Jupyter Lab

단축키

ESC : 명령모드
1. Y : Code Cell (코드 편집)
2. M : Markdown Cell (마크다운 으로 표현)
3. A : 현재 셀 위에 셀 만들기
4. B : 현재 셀 아래에 셀 만들기
5. dd : 현재 셀 삭제하기

마크다운

  1. Header : #, ##, ###
  2. italic : _ , *
  3. bold : __ , **
  4. ~strikethrough : ~
  5. unordered list : - , ...
  6. ordered list : 1.

💦 공부하며 어려웠던 내용


0개의 댓글