[Python Selenium_macOS] 카이스트 윤리 및 안전 수강 크롤링 매크로 _인권편

Fire Pit·2022년 2월 23일
0
post-thumbnail

KAIST 윤리 및 안전 [Human Rights and Gender Equality] 전용 코드입니다


카이스트 석사과정 신입생은 의무적으로 들어야하는 윤리 수업. 수강할 내용은 많고, 진득하게 앉아서 듣기 힘든 일이다. 그냥 라디오처럼 틀어둘 수는 없을까? 10분마다 와서 종료 버튼 누르고 끄기는 꽤 귀찮은 일이다. 그렇다고 듣지 않자니 시험도 봐야하고, 어느정도 귀에 담아두는건 필요하겠다 싶어서 짜본 나의 크롤러.

Objective

  • 'KAIST 윤리 및 안전'의 과목별 강의 목록을 자동으로 수강하는 알고리즘.
  • 강의 종료 후, 일일히 클릭할 필요 없이 자동으로 그 다음 강의를 재생한다.

Coding Environment
macOS, Python, Selenium, Jupyter Notebook

0. 개발 환경 세팅하기

a) 파이썬 3.x 이상 설치

https://www.python.org/downloads/
파이썬 홈페이지에서 3.x 이상 버전을 설치한다. pip이 자동으로 설치되어있기 때문이다.
pip을 통해 우리가 필요한 selenium을 비롯한 여러 모듈들을 온라인에서 불러올 수 있다.

b) 셀레니움 설치

웹크롤링을 위한 모듈로, 인터넷 브라우저를 직접적으로 조작(클릭, 입력)하는 데 쓰인다. 특히 javascript 같이 동적으로 짜여진 웹 페이지를 조작할 수 있다. 여기서 셀레니움을 통해 웹 페이지를 클릭하며 자동화를 할 것이다.
Pycharm을 이용한다면 다들 아래 메시지를 terminal에 입력해서 설치한다 :

sudo pip install selenium	//MacOS

그런데, 나는 왜인지 이렇게 해도 Pycharm에 설치가 되지 않아서, Pycharm에서 Interpreter Setting을 통해서 Install 했다. 하지만 실제로 작업하는 과정에서 Pycharm을 사용하지 않게 되면서 위 과정은 필요가 없게 됐다. Anaconda를 설치하면 Jupyternotebook에 selenium이 자동으로 내장되어 있기 때문이다.

c) Anaconda 설치 및 Jupyter Notebook 런치

https://www.anaconda.com/products/individual
Jupyter Notebook을 이용하면, selenium을 따로 설치하지 않아도 되고, 또 단계별로 실행 상황을 분리해서 코드를 짤 수 있기 때문에 이 편이 Pycharm 보다 편하다. Pycharm은 코드를 수정할때마다 1번 줄부터 코드를 다시 읽지만, Jupyternotebook은 단계별로 분리해서 실행해 볼 수 있기 때문에 훨씬 직관적이다.

d) 크롬 드라이버 설치

http://chromedriver.chromium.org/
크롬 드라이버는 크롬 브라우저를 컨트롤 할 수 있게 해주는 파일이다. 코드를 입력하는 개발 환경과 크롬 브라우저 사이를 연결해주는 다리 역할을 하는 것이다. 자신이 사용하는 크롬의 버전과 맞는 것으로 위 링크에서 다운받은 뒤, 작업할 파이썬 파일과 같은 폴더에 넣어준다.

1. 셀레니움 모듈 불러오기 @ Jupyter Notebook

from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.alert import Alert
from selenium.webdriver.common.by import By
import time

2. 웹드라이버 정의 및 실행하기

이제 코드를 짤 준비가 다 끝났다. 우리는 이 driver을 불러옴으로써 브라우저에 명령을 내릴 수 있다.

driver = webdriver.Chrome()

3. 윤리 강의 홈페이지에 로그인하기 (Human Rights 강의)

여기서부터는 우리가 마우스와 키보드로 조작을 하는 과정을 코드로 구현해 볼 것이다.
사용한 메소드는 다음과 같다.

- driver.get('url') : url에 접속한다.
- driver.find_element(By.XPATH, 'xpath').click( ) : 특정 요소를 찾고 클릭한다.
- driver.find_element_by_xpath('xpath') : 내가 사용하는 셀레니움 버전에서는 이 방식이 구 버전이라는 warning이 떴다. 그래서 바로 위 방법 사용함.
- driver.implicitly_wait( ) : 페이지가 로드될 때 까지 기다린다. 단 n초가 지나면 다음 명령으로.

# 웹사이트 접속
driver.get('https://humanrights.kaist.ac.kr/')
driver.implicitly_wait(3)

# '나의 강의실'클릭
driver.find_element(By.XPATH, '//*[@id="contents"]/div/div/div[2]/div[1]/ul/li[1]').click()
da = Alert(driver)
da.accept() # 팝업 처리

# '포탈 로그인' 바로가기 클릭
driver.find_element(By.XPATH, '//*[@id="content"]/p[2]').click()

# 카이스트 통합 로그인 새 페이지 -> 아이디입력
driver.find_element(By.ID, "IdInput").send_keys('sojungnoh')
# 간편 인증 클릭
driver.find_element(By.XPATH, '/html/body/div/div/div[2]/div/div/fieldset/ul/li[2]/input[1]').click() 
# 여기서 얼굴 인증 -> 페이지 닫음
driver.implicitly_wait(5) # 이후 자동으로 메인 페이지 안착

*로그인 관련
셀레늄 로그인 관련해서 검색을 해보면 보통 ID와 PW를 입력하는데, 카이스트는 로그인이 좀 까탈스러워서 모바일로 얼굴을 인증해야 한다. 다행히 이런 과정이 코드를 짜는데 별 문제를 만들지 않았다. 폰에 페이스아이디 메시지가 오면 그냥 인증을 해주면 된다. 그럼 자동으로 다음 명령으로 넘어간다.

*Message: no such element: Unable to locate element
필요한 코드를 입력하고 실행하면 가끔 위와 같은 메시지가 뜰 때가 있다. 그럴 땐 브라우저가 요소를 전부 다 로드하기도 전에 명령이 실행된 것이기 때문에 element를 찾지 못한 것이다. 그럴땐 기다려줘야 한다. 다음 링크에 좋은 설명이 있다.
https://pythondocs.net/selenium/%EC%85%80%EB%A0%88%EB%8B%88%EC%9B%80-wait-%EA%B0%9C%EB%85%90-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0-implicitly-wait-vs-explicitly-wait/

4. 강의 목록 접근

# '나의강의실'클릭
driver.find_element(By.XPATH, '//*[@id="contents"]/div/div/div[2]/div[1]/ul/li[1]').click()
# '학습하기' 클릭
driver.find_element(By.XPATH, '//*[@id="content"]/table/tbody/tr[2]/td[3]/a[1]').click()

5. 플레이어 클릭 및 자동 연속 재생 ★

이 부분이 이번 미니 프로젝트의 핵심적인 부분이다. 한 강의가 끝나면 자동으로 다음 강의를 재생해주는 알고리즘! 이 부분에서 시행착오가 많은데, 주피터 노트북을 사용한 것이 빛을 발하는 지점이었다. 이 부분만 잘라서 실행해볼 수 있기 때문.

수업 목록xpathvariable
1강'//*[@id="content"]/table/tbody/tr[2]/td[4]/a'2
2강'//*[@id="content"]/table/tbody/tr[3]/td[4]/a'3
3강'//*[@id="content"]/table/tbody/tr[4]/td[4]/a'4
n강'//*[@id="content"]/table/tbody/tr[5]/td[4]/a'n+1

강의별로 동영상 재생 버튼이 갖고 있는 xpath의 패턴을 파악해 {}로 비워두고, format을 활용해 반복문에 적용되도록 했다.강의 개수가 29개이므로 range를 (2, 30)으로 하면 된다.

#플레이어 클릭 및 재생 반복
for i in range(2,30):
    # 수강항목 선택
    driver.find_element(By.XPATH, '//*[@id="content"]/table/tbody/tr[{}]/td[4]/a'.format(i+1)).click()
    driver.implicitly_wait(5)
    # 팝업 뜨면 재생버튼 클릭
    driver.find_element(By.ID, 'play-pause-button').send_keys(Keys.ENTER)
    wait = WebDriverWait(driver, 600) 
    wait.until(EC.alert_is_present()) # 알람이 등장할때까지 기다려라. 단 600초가 지나면 다음으로
    # 종료되면 
    da = Alert(driver)
    da.accept()
    print('{}차 수강완료'.format(i))

print('수강종료')

send_keys(Keys.ENTER) : 동영상 플레이어에 click( )메소드가 안먹는다. 요소가 화면을 벗어났다는 뜻인것 같다. 그럴땐 send_keys()메소드로 대체.

Alert(driver).accept( ) : 이놈의 홈페이지는 팝업이 참 많이 뜬다. 팝업은 크롬 console에서 html코드로 찾을 수 없었다. 그래서 '셀레니움 팝업'이라고 검색해보니 팝업에 대응하는 별도 방법이 있었다. 셀레늄 라이브러리에서 Alert를 불러와 확인을 누르는 메소드다.

재생을 해보면 완료가 될때마다 수강이 완료되고, 동시에 다음과 같은 결과를 얻을 수 있다.

1차 수강완료
2차 수강완료
.
.
.
28차 수강완료
29차 수강완료

P.S. 중간중간 딴 짓을 하려고 짠 코드였는데, 이걸 실행시켜놓고 이 글을 쓰면서 꽤나 집중해서 Human Rights and Gender Equality를 듣게 됐다. 그저 고루한 내용이겠거니 했는데 생각보다 집중해서 들을만한,, 아니 들어야 하는 내용의 윤리 강의였다. 혹시라도 이 글을 보고 계시는 분도 틀어놓고 소리를 꺼두기보단, 라디오처럼 들으시면 좋겠다.

profile
Burning everyday to gain FIRE!

0개의 댓글