본문 바로가기

데이터엔지니어링

[2주차] 파이썬으로 웹다루기 (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

driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))	# Chrome 실행
driver.get('http://www.example.com')
print(driver.page_source)

## with 구문으로 변경 (브라우저를 자동으로 열고 닫기 위함)
with webdriver.Chrome(service=Service(ChromeDriverManager().install())) as driver:
	driver.get('http://www.example.com')
	print(driver.page_source)

## 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

Selenium은 동적 웹 사이트에 대한 지원을 진행하기 위해 두 가지 Wait을 지원

 

Implicit Wait

로딩이 다 될 때까지 지정한 시간 동안 기다림 (ex. 로딩이 다 될 때까지 5초 동안 wait)

 

Explicit Wait

특정 요소에 대한 제약을 통한 기다림 (ex. 이 태그를 가져올 수 있을 때까지 wait)

 

XPath: xml + path

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

(ex. 데스크탑/폴더1/폴더2/음악.mp3)

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

url = 'https://indistreet.com/live?sortOption=startDate%3AASC'
xpath = '//*[@id="__next"]/div/main/div[2]/div/div[4]/div[1]/div[1]/div/a/div[2]/p[1]'

with webdriver.Chrome(service=Service(ChromeDriverManager().install())) as driver:
	driver.get(url)
    driver.find_element(By.XPATH, xpath).text # 로딩 되기 전에 find_element를 찾기 때문에 오류 발생
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from webdriver_manager_chrome import ChromeDriverManager

url = 'https://indistreet.com/live?sortOption=startDate%3AASC'
xpath = '//*[@id="__next"]/div/main/div[2]/div/div[4]/div[1]/div[1]/div/a/div[2]/p[1]'
  
# Implicit Wait
with webdriver.Chrome(service=Service(ChromeDriverManager().install())) as driver:
	driver.get(url)
    driver.implicitly_wait(10)
    print(driver.find_element(By.XPATH, xpath).text)

 

WebDriverWait()과 두 메서드를 활용해 Explicit Wait 적용

 

until(): 인자의 조건이 만족될 때까지

until_not(): 인자의 조건이 만족되지 않을 때까지

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

from selenium.webdriver.support import expected_conditions as EC

url = 'https://indistreet.com/live?sortOption=startDate%3AASC'
xpath = '//*[@id="__next"]/div/main/div[2]/div/div[4]/div[1]/div[1]/div/a/div[2]/p[1]'

# Explicit Wait
with webdriver.Chrome(service=Service(ChromeDriverManager().install())) as driver:
	driver.get(url)
    element = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, xpath)))
    print(element.text)

 

✔  여러 공연 제목 가져오기

이 페이지의 공연 제목에 해당하는 XPath

//*[@id="__next"]/div/main/div[2]/div/div[4]/div[1]/div[1]/div/a/div[2]/p[1]

//*[@id="__next"]/div/main/div[2]/div/div[4]/div[1]/div[2]/div/a/div[2]/p[1]

//*[@id="__next"]/div/main/div[2]/div/div[4]/div[1]/div[3]/div/a/div[2]/p[1]

...

10개의 이름을 가져오는 코드 작성

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

from selenium.webdriver.support import expected_conditions as EC

url = 'https://indistreet.com/live?sortOption=startDate%3AASC'

with webdriver.Chrome(service=Service(ChromeDriverManager().install())) as driver:
	driver.get(url)
    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)

🙂 마우스 이벤트 처리

해시코드 '로그인'창 접속: https://hashcode.co.kr/

✔  Mouse Event

Event: 웹 페이지에서 일어나는 일

  • 마우스 움직이기(move)
  • 마우스 누르기(press down)
  • 마우스 떼기(press up)
  • ...

마우스 입력

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

id가 button인 요소를 클릭하는 예제

button = driver.find_element(By.ID, 'button')
ActionChains(driver).click(button).perform()

✔  홈페이지에서 로그인 창 접근

  1. 로그인 페이지 버튼 접근
  2. 클릭 이벤트 전달
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

url = 'https://hashcode.co.kr/'

driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))
driver.get(url)
driver.implicitly_wait(0.5)

button = driver.find_element(By.CLASS_NAME, 'nav-link.nav-signin')
ActionChains(driver).click(button).perform()

 

로그인 창 진입 후 키보드 이벤트 처리


🙂 키보드 이벤트 처리

✔  Keyboard Event

  • 키보드 누르기(press down)
  • 키보드 떼기(press up)
  • ...

키보드 입력

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

id가 textInput인 요소에 'abc'를 입력하는 예제

text_input = driver.find_element(By.ID, 'textInput')
ActionChains(driver).send_keys_to_element(text_input, 'abc').perform()

 

✔  로그인 창

  1. 이메일 입력
  2. 비밀번호 입력
  3. 로그인 하기 클릭
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

import time

url = 'https://hashcode.co.kr/'

driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))
driver.get(url)
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.ID, 'btn-sign-in')
ActionChains(driver).click(login_button).perform()
time.sleep(1)

🙂 Appendix Jupyter Lab

✔  Jupyter Lab

다양한 Text Editor, IDE 등을 통해 개발

Interactive한 Python 코드 작성 / 공유를 위한 개발 도구

 

Jupyter Lab 설치하기

  1. 터미널에서 pip install jupyterlab
  2. jupyter lab 명령을 통해 시작
  3. Notebook - Python 3를 통해 새로운 노트북(.ipynb) 파일 생성

노트북 모드

명령 모드 입력 모드
Cell에 대한 명령을 내릴 때 Cell에 내용을 입력할 때
Mode: Command Mode: Edit
Enter로 입력모드 변경 Esc로 명령 모드 변경

 

셀 종류

Code Cell Markdown Cell
python 코드 markdown 문법으로 필기
M로 Markdown Cell 변경 Y로 Code Cell 변경

 

명령 모드에서의 단축키

  • A: 현재 Cell 위에 새로운 Cell 추가
  • B: 현재 Cell 아래에 새로운 Cell 추가
  • dd: 현재 Cell 삭제
  • ctrl/cmd + Enter를 통해 현재 Cell 실행
  • Y: Code Cell
  • M: Markdown Cell

 

✔  Markdown

일반 텍스트로 서식이 있는 문서를 작성하는 방법

문법

  • Header: #, ##, ###, ...
  • Italic: *...*, _..._
  • Bold: **...**, __...__
  • Strikethrough: ~...~
  • Unordered List:  -..., *...
  • Ordered List: 1. ..., 2. ...
  • Code: `...`
  • Code Block: ```...```
  • 개행: space + space