파이썬으로 웹 다루기 (4)

PH_Lee·2024년 4월 4일

브라우저 자동화하기, Selenium

selenium은 Python을 이용해서 웹 브라우저를 조작할 수 있는 자동화 프레임워크

#selenium 설치
%pip install selenium

Web Driver

WebDriver는 웹 브라우저를 제어할 수 있는 자동화 프레임워크

#webdriver-manager 설치
%pip install webdriver-manager

Selenium 시작하기

# selenium으로부터 webdriver 모듈을 불러옵니다.
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager

# 불러온 모듈 webdriver에서 Chrome() 객체를 생성
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))

# http://www.example.com 으로 요청을 보내봅시다.
driver.get("http://www.example.com")

# page_source 속성을 확인해봅시다.
print(driver.page_source)

# with-as 구문을 통해 주어진 명령이 끝나면 driver를 종료하도록 설정할 수 있습니다.
with webdriver.Chrome(service=Service(ChromeDriverManager().install())) as driver:
    driver.get("http://www.example.com")
    print(driver.page_source)

Driver에서 특정요소 추출하기

요소 하나 찾기

  • .find_element(by, target)
    by: 대상을 찾는 기준 : ID, TAG_NAME, CLASS_NAME,...
    target: 대상의 속성

요소 여러개 찾기

  • .find_elements(by, target)
    by: 대상을 찾는 기준 : ID, TAG_NAME, CLASS_NAME,...
    target: 대상의 속성
# By를 import해봅시다.
from selenium.webdriver.common.by import By

# p 태그에 해당하는 요소 하나를 찾아봅시다.
with webdriver.Chrome(service=Service(ChromeDriverManager().install())) as driver:
    driver.get("http://www.example.com")
    print(driver.find_element(By.TAG_NAME, "p").text)
    
# p 태그에 해당하는 요소 여러개를 찾아봅시다.
with webdriver.Chrome(service=Service(ChromeDriverManager().install())) as driver:
    driver.get("http://www.example.com")
    for element in driver.find_elements(By.TAG_NAME, "p"):
        print("Text", element.text)

Wait and Call

스크래핑을 방지할 목적으로 랜덤하게 class 이름을 생성하는 경우도 있다.
이러한 경우 위치를 활용한 방법을 사용하기도 한다.

Xpath

XML, HTML 문서 등의 요소의 위치를 경로로 표현하는 것

예시 사이트 : https://indistreet.com/live?sortOption=startDate%3AASC

# 예시 사이트에 요청을 진행하고, 예시 사이트의 첫 번째 이벤트의 제목을 가져와봅시다.
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))
driver.get("https://indistreet.com/live?sortOption=startDate%3AASC")
driver.find_element(By.XPATH, '//*[@id="__next"]/div/main/div[2]/div/div[4]/div[1]/div[2]/div/a/div[2]/p[1]').text

-> 동적 웹페이지 이기 때문에 오류가 발생한다.

Implicit Wait

암시적 기다림, 반드시 해당시간을 기다리는 것이 아니라, 로딩이 다 될때까지의 한계시간의 의미를 가진다.

# 10초동안 Implicit Wait을 진행하도록 해서 스크래핑이 잘 이루어지도록 수정해봅시다.
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")
    driver.implicitly_wait(10)
    print(driver.find_element(By.XPATH, '//*[@id="__next"]/div/main/div[2]/div/div[4]/div[1]/div[2]/div/a/div[2]/p[1]').text)

Explicit Wait

WebDriverWait()과 until(), until_not()을 활용하여 명시적 기다림을 적용할 수 있습니다.
until(): 인자의 조건이 만족될 때까지
until_not(): 인자의 조건이 만족되지 않을 때까지

# Explicit Wait를 활용해서 스크래핑이 잘 이루어지도록 코드를 작성해봅시다.
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")
    element = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, '//*[@id="__next"]/div/main/div[2]/div/div[4]/div[1]/div[2]/div/a/div[2]/p[1]')))
    print(element.text)

여러 공연 제목 가져오기

# 10개 공연의 제목을 스크래핑하는 코드를 작성해봅시다.
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)

마우스 이벤트 처리하기

  1. 입력하고자 하는 대상 요소를 찾는다.
  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.CLASS_NAME, "nav-link.nav-signin")
ActionChains(driver).click(button).perform()

키보드 이벤트 처리하기

  1. 입력하고자 하는 대상 요소를 찾습니다.
  2. 입력하고자 하는 내용을 send_keys_to_element를 통해 전달합니다.
  3. 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를 이용해 해당 사이트에 요청을 보내봅시다.
import time

driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))
driver.get("https://hashcode.co.kr/")
time.sleep(1)

# 내비게이션 바에서 "로그인" 버튼을 찾아 눌러봅시다.
button = driver.find_element(By.CLASS_NAME, "nav-link.nav-signin")
ActionChains(driver).click(button).perform()
time.sleep(1)

# "아이디" input 요소에 여러분의 아이디를 입력합니다.
id_input = driver.find_element(By.ID,"user_email")
ActionChains(driver).send_keys_to_element(id_input, "여러분의 아이디").perform()
time.sleep(1)

# "패스워드" input 요소에 여러분의 비밀번호를 입력합니다.
pw_input = driver.find_element(By.ID,"user_password")
ActionChains(driver).send_keys_to_element(pw_input, "여러분의 패스워드").perform()
time.sleep(1)

# "로그인" 버튼을 눌러서 로그인을 완료합니다.
login_button = driver.find_element(By.CLASS_NAME, "btn-sign-in")
ActionChains(driver).click(login_button).perform()
time.sleep(1)
profile
새싹 개발자

0개의 댓글