☆IT 개발 프로그램☆/Phthon

[파이썬/Python] 티켓팅 자동화 매크로 개발해보기

호기심을 품고사는 중 2020. 6. 4. 15:05

처음에 블로그를 개설할 때는, 유익한 IT블로그를 만들겠다는 야심찬 포부가 있었는데,  IT 포스트로 유입이 거의 전혀 없다시피 하다보니, 아무래도 잘 하지 않게 됩니다. 물론 유입이 없는 건 제 포스팅 역량 부족 + 개발 역량 부족 때문이지만서도요...ㅎㅎㅎ

무튼 개인적 호기심으로 만들어 보았던 티켓팅 자동화 매크로 코드입니다.

저는 업무외에 혼자서 코딩할때에는 거의 파이썬으로 합니다.


구현 알고리즘

 

티켓팅 자동화를 구현하기 위해서 3가지 방법을 고려할 수 있습니다.

 

1. 좌표를 설정하여 자동화 구현

2. 각 엘리멘트를 바로 실행시키는 웹 자동화 형식

3. 서버단에 예매정보 패킷 전송

 

좌표 설정법은, UI적으로 위치적 변화가 있을 경우 작동하지 않는다는 단점이 있습니다. 웹 자동화 형식은 좌표 변화에는 조금 더 유연하게 대처할수 있지만 element 내부에서 변화가 있다면 작동하지 않을 지도 모릅니다.

1, 2번은 클라이언트 단에서 단순히 사용자 작업을 자동화하는 방법인 반면, 3번은 서버단 데이터 조작을 시도하므로 불법입니다. (그래서 이 방법으로 대리예매를 해주는 대리티케터들에게 본인 아이디를 제공하는 게 실은 위험한 일입니다. 대리예매자는 VPN을 이용해 본인의 IP와 개인정보를 철저히 보호할수 있지만, 해킹을 시도하는 ID에 담긴 개인정보는 내 것이기 때문에, 법적인 책임은 ID소유자인 나 혼자서 온전히 지게 될수 있거든요.) 

 

 

Python 셀레늄 API로 웹 자동화 매크로를 구현하겠습니다. 로그인, 페이지로드, 날짜지정까지 자동화로 진행하고, 그 이후의 과정은 사용자가 직접 진행하는 아주 간단한 자동화 매크로입니다.

 


 

전제 조건 (Prequisite)

셀레늄은 내장 라이브러리가 아니기 때문에 별도 설치를 요합니다. 콘솔에서 pip로 간단히 설치할 수 있습니다.

python3 --version
Python 3.7.3

pip3 install selenium

Pycharm 사용자는 Preference - Version Control - Project Interpreter 에서 설치할 수도 있습니다.


코드

셀레늄 라이브러리를 임포트합니다.

# main.py

import time
from datetime import datetime
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import pause

 

티켓팅 페이지 주소, 아이디, 비밀번호, 티켓팅 날짜등의 변수가 필요합니다. 나중에 커스터마이징이 용이하도록 config 스크립트를 별도로 만들어 관리하겠습니다

# macro_config.py

url = https://www.myticket.com/nct127/iloveblackpinktoo.aspx

my_id = thisismyid
my_pw = thisismypw

start_year=2019
start_month=2
start_date=27
start_hour=20
start_min=0

 

셀레늄은 크롬보다는 파이어폭스에서 보다 더 안정적이라는 평가를 받습니다. 파이어폭스로 구동하겠습니다.

# main.py

import macro_config as mc

driver = webdriver.Firefox()

wait = WebDriverWait(driver, 10)

driver.get(mc.url)

 

스크립트를 실행하면 셀레늄 드라이버가 컨피그 파일에 저장된 url 주소를 로드합니다. 로드되면 로그인을 시킬것입니다. 저는 셀레늄 드라이버가 로그인에 필요한 element들을 element의 id로 찾아오도록 하겠습니다. "id"가 아니라 "name", "class"를 이용할 수도 있습니다. 그 경우 find_element_by_id 메소드를 name이나 class로 element를 찾아오는 메소드로 수정합니다. 드라이버는 id input, pw input element를 찾아서, element에 실제 아이디와 패스워드를 입력하고 로그인버튼을 클릭할 것입니다.

id_elem = wait.until(EC.element_to_be_clickable((By.ID, "userID")))
pass_elem = driver.find_element_by_id("userPW")

id_elem.send_keys(mc.my_id)
pass_elem.send_keys(mc.my_pw)

login_elem = driver.find_element_by_id("loginBtn")
login_elem.click()

 

로그인을 완료한 후, 정확히 티켓팅 시작 시간에 드라이버가 티켓팅 페이지를 로드하도록 하겠습니다.

pause.until(datetime(mc.start_year, mc.start_month, mc.start_date, mc.start_hour, mc.start_min, 00))

driver.get(mc.url)

 

티켓팅 페이지가 로드되면, 예매하기 버튼 element을 찾아서 클릭하게 하겠습니다. 이번에는 id가 아닌 class로 예매하기 element를 찾아오겠습니다.

 

res_elem = wait.until(EC.element_to_be_clickable((By.CLASS_NAME, 'rbtn.rbt_reserve')))
res_elem.click()

 

새 팝업창이 생성되었습니다. 작업창을 새 팝업창으로 바꿔준 후, 날짜 element를 찾아 클릭하게 합니다. 

 

driver.switch_to_window(driver.window_handles[1])

date_elem = wait.until(EC.element_to_be_clickable((By.ID, '2019-06-30')))
date_elem.click()

 

이렇게 날짜 선택까지 동작하는 매크로를 만들어 보았습니다.


덧붙이는 말

1. 실제 티켓 판매 사이트의 UI를 예시로 사용하였지만, element의 id, class 등의 정보는 해당 사이트의 소스와 다릅니다.

2. 매크로의 이용 행위는 불법이 아니지만, 매크로를 이용하여 재산상 이득을 취하는 행위를 할 경우 불법입니다.