파이썬 예약 매크로 - paisseon yeyag maekeulo

ㅎㅎ. 간만에 보는 "해킹은 어떻게 하나요" 급 질문인데요.

1. 보통은 그런 발상을 하는 사람을 막기 위해 CAPTCHA가 있습니다.

널리 쓰이는 CAPTCHA를 푸는 건, 절대 불가능 까지는 아니더라도...

(1) "python selenium?? 라이브러리 같은 것을 쓰면 된다고 하는데요" 같은 질문을 하는 수준에서는 일단 요원하고요.

(2) 만약 정말로 잘 쓰이는 CAPTCHA를 정면으로 뚫을 정도의 기술이 있다면, "유명 콘도 및 골프 사이트 예약" 같은 시시한 문제에 연연할 필요가 없을걸요.

2. CAPTCHA가 없다면 그럼 만사형통일까요?

기술적 난이도만 문제가 되는 게 아니죠. 요점은 "희소한 보상을 위해 수많은 사람들이 경쟁"한다는 것 아니겠습니까?

귀하께서 쉽게 오토메이션을 짜서 도전할 수 있다면 남들도 그러겠지요.

보통 경쟁률이 높은 선착순 사이트에서 이런 오토메이션에 대한 대비가 없으면, 오토메이션을 돌려서 매점하려고 드는 사람이 꼭 나타나기 마련입니다.

(보통은 그런 사람들을 막기 위해서 CAPTCHA 같은 방어를 하는 것이기도 하고요.)

조그마한 기술적 우위로 남들보다 앞서려는 생각을 했다면 순진한 발상이라고 볼 수밖에요.

3. 그래도 공부를 하시고 싶다면...

파이썬이야 요즘 워낙 널리 쓰이는 언어라 적당히 유명한 교본 하나 잡고 공부하시면 될 거고요.

저는 일단 이 책 한 권 추천 드립니다: http://book.naver.com/bookdb/book_detail.nhn?bid=14649485

기존 확장프로그램으로 쓰던 SRT 예매 매크로가 막혀서 손크로를 할 수 밖에 없다.

하지만 그러기에는 너무 귀찮기때문에 파이썬과 셀레니움을 통해서 만들어 보도록 하자.

개발공부하는 겸해서 겸사겸사 만들어 보도록 하겠다. 

이것은 어떻게 개발을 했는지 흔적을 남기기 위해서 작성하는 글이다.

잘 만들어져가지고 완성되면 나 혼자 잘 써야겠다.ㅎㅎㅎ

먼저 개발했던 사람이 있어서 해당 분의 소스코드를 기반으로 커스터마이징을 진행할 것이다.

kminito.tistory.com/25

[Python] 파이썬으로 SRT 매진 표 예매하기 (+셀레늄)

 파이썬으로 SRT 표 예매 과정을 자동화 한 것입니다. 웹에서의 동작은 셀레늄을 이용했습니다. 아래 내용을 보시면 아시겠지만 단순히 사람이 하는 반복 작업을 파이썬을 통해 자동화 한 것이

kminito.tistory.com

파이썬 예약 매크로 - paisseon yeyag maekeulo

위 블로거의 소스코드를 기반으로 커스터마이징을 진행할 것이다.
(초반 설계가 힘든데 다 해주셔서 공수를 많이 줄일 수 있을거 같다.. 위 블로그도 들려주길 바란다)

해당 블로그의 소스코드를 하나 하나씩 타이핑하여 적었다. 앞으로 수정할 부분을 이번 글에 나열해보겠다. 

더보기

# -*- coding: utf-8 -*-

import os
import sys
import datetime
import requests
from time import sleep
from random import randint
from bs4 import BeautifulSoup
from selenium import webdriver
from selenium.webdriver.support.ui import Select

def open_browser():
    options = webdriver.ChromeOptions()
    #option.add_argument('headlees')
    options.add_argument('window-size=1920x1080')
    options.add_argument("disable-gpu")
    driver = webdriver.Chrome("C:\selenium\chromedriver", chrome_options=options)
    return driver

def run():
    driver = open_browser()
    driver.get('https://etk.srail.co.kr/cmc/01/selectLoginForm.do')
    driver.implicitly_wait(15)
    driver.find_element_by_id('srchDvNm01').send_keys("SRT 회원번호") #아이디
    driver.find_element_by_id('hmpgPwdCphd01').send_keys("SRT 비밀번호") #비번
    driver.find_element_by_xpath('//*[@id="login-form"]/fieldset/div[1]/div[1]/div[2]/div/div[2]/input').click()('//*[@id="login-form"]/fieldset/div[1]/div[1]/div[2]/div/div[2]/input').click()
    # 보내기
    driver.implicitly_wait(4)
    sleep(0.4)
    driver.find_element_by_xpath('//*[@id="search-form"]/fieldset/div[1]/a').click() # 도착, 시간 등
    driver.implicitly_wait(1)
    driver.find_element_by_id("ui-id-{}".format(dpt_locs[dpt])).click() #도착지
    sleep(0.4)
    driver.find_element_by_xpath('//*[@id="search-form"]/fieldset/div[2]/a').click()
    driver.implicitly_wait(1)
    driver.find_element_by_id("ui-id-{}".format(avl_locs[avl])).click() #출발지
    date_ele = driver.find_element_by_xpath('//*[@id="search-form"]/fieldset/div[3]/div/input[1]')
    driver.execute_script("arguments[0].setAttribute('value','{}')".format(dpt_date), date_ele)
    driver.find_element_by_xpath('//*[@id="search-form"]/fieldset/div[4]/a').click()
    driver.find_element_by_xpath('//*[@id="search-form"]/fieldset/a').click()
    driver.implicitly_wait(4)
    sleep(0.4)

    counter =1
    while True:
        soup = BeautifulSoup(driver.page_source,'html.parser')
        trlist = soup.select('#result-form > fieldset > div.tbl_wrap.th_thead > table > tbody > tr')
        index=0
        done=False
        for tdl in trlist:
            if done ==False:
                index += 1
                for train_no in train_nums:
                    if tdl.select('.trnNo')[0].text.strip() == str(train_no):
                        if '예약하기' in tdl.select("td")[6].find_all(text='예약하기'):
                            t = "#result-form > fieldset > div.tbl_wrap.th_thead > table > tbody > tr:nth-child(" + str(index) + ") > td:nth-child(7) > a"
                            driver.find_element_by_css_selector(t).click()
                            print("예약완료----------------------------------------------------------")
                            done=True
                            break
                        else:
                            sleep(0.3)
                else:
                    break
            print("loop done. count : {}".format(counter))
            sleep(randint(5,10))
            if done == False:
                elm = driver.find_element_by_xpath('//*[@id="search_top_tag"]/input')
                driver.execute_script("arguments[0].click();", elm)
                driver.implicitly_wait(2)
                counter+=1
            else:
                driver.quit()
                break

            if counter > 240:
                print("loop 2004 done")
                break

if __name__ == "__main__":
    dpt = input("출발지 입력 (ex 동탄, 울산, 동대구, 수서, 천안아산) : ")
    avl = input("도착지 입력 - 출발지랑 마찬가지")
    dpt_date = input("날짜 입력. 반드시 2019.12.31 형태 : ")
    when = input("6시 or 16시 둘중 하나 : ")
    train_nums = list(map(int,input("기차 번호 입력 스페이스바로 구분 : ").strip().split()))
    run()

1. SRT 회원번호가 아닌 이메일주소로 로그인 및 이메일 주소,비밀번호 입력받아서 처리(run,25 / main)
1-1. 로그인 실패시  다시 진행할 수 있도록
2. 출발지 및 도착지를 바로 확인해서 입력할 수 있도록 처리
3. 출발지 및 도착지 에러나는거 수정(33,37)
4. 예약하기 및 예약대기 부분 바뀐거 맞춰서 찾을 수 있도록 하기
5. 6시 or 16시 형태를 바꿀 수 있는거 고민
6. 예매가 되면 트럼펫이나 아무거나 소리나게 만들기
7. 접근성 좋게 exe나 이거저것으로 고치기
8. 이거를 기반으로 각 기능별로 포스팅하면 좋을 듯