야매코딩/파이썬

파이썬 1도 모르는데 챗gpt로 예약 매크로 만들기 - 1

귤덕후 2025. 2. 11. 15:24

 

코딩은 전혀 할 줄 모르지만 관심은 있는 그런 상태로 살던 어느 날,

유튜브에 '기차 티켓팅 5초 만에 예약' 영상을 보게 되었고 영상 속 코딩 화면이 눈에 띄었다.

 

원래라면 질겁하며 도망쳤겠지만 지금은 다르다. 

나는 챗gpt가 함께 있잖아?

 

지금부터 `**야매 코딩에 주의하세요!**`

 

 

 

매크로 작업환경 세팅

 

 

 

파이썬 설치는 필수 https://www.python.org/downloads/

+ 효율적인 작업을 위해 vscode 도 설치 https://code.visualstudio.com/download

 

 

매크로는 파이썬의 웹 자동화 도구를 활용한다. 보통 `selenium` 같은 라이브러리를 쓴다.

vscode 밑에 뜨는 터미널에다가 아래 명령어를 입력한다.

 

pip install selenium #매크로를 위한 셀레니움 라이브러리 설치
pip install pytz #파이썬에서 시간대를 다루기 위해 설치

 

 

 

특정 웹브라우저를 제어하기 위해 웹 드라이버를 설치해야 하는데, 나는 크롬을 쓸 예정이라 ChromeDriver를 설치해 줬다.

본인의 크롬 버전에 맞게 다운받아야 하는데 난 크롬 버전이 133이라 아래 링크에서 다운을 받았다.  

https://googlechromelabs.github.io/chrome-for-testing/

 

나는 m1 맥북이라 mac-arm64 링크로 다운받음

 

 

 

다운받은 ChromeDriver 링크를 코드 상에 연결해줘야 한다. 

Selenium 4에서는 `service` 객를 사용하여 `chromedriver` 경로를 지정해야 하기 때문에 아래와 같이 코드를 완성했다.

 

from selenium import webdriver
from selenium.webdriver.chrome.service import Service

# ChromeDriver 경로 설정 
service = Service('/크롬드라이버 경로')

# WebDriver에 Service 객체 전달
driver = webdriver.Chrome(service=service)

 

 

 

 

사이트 구조 파악하기

 

 

이번에 구현해 보려는 기능은

자동으로 로그인하고, 예약버튼 누르고, 전화번호 등 인적사항도 자동으로 입력하는 기능이다.

 

인터넷은 HTML 코드로 이루어져 있고, 그 안에는 `div`, `p`, `a` 와 같은 태그들이 무수히 많다. 

여기서 로그인 버튼, 입력 탭 등의 '정확한 위치'를 전달하기 위해 `XPath`를 이용한다. 일종의 좌표값인 셈.

 

`XPath`를 파악하기 위해선 우클릭을 해제해야 하는데 대부분의 예약 페이지는 우클릭을 막아 놨기 때문에 크롬 확장프로그램을 설치해서 쉽게 우클릭을 허용해 준다. 

 

 

Right Click Enable - 오른쪽 클릭 활성화 - Chrome 웹 스토어

우클릭 활성화 - 효과적이고 편리한 컨텍스트 메뉴 활성화기가 차단된 사이트에서 우클릭 메뉴를 허용하도록 합니다.

chromewebstore.google.com

 

 

 

그런 다음 예약버튼 위 우클릭 - 검사를 눌러주면 괴랄하지만 뭔가 있어 보이는 영어들이 뜨는데

거기서 음영처리 된 부분 위에서 또 우클릭 - copy - copy XPath를 해주면 된다. 

 

 

 

 

 

그럼 아마 `//*[@id =`이런 모양으로 얻은 문자열이 나올 텐데 이걸 예약 버튼 관련 코드의 `By.XPATH` 값에 넣어주면 된다.

 

지금은 예시가 예약버튼이지만 자동 로그인을 원하면 로그인 버튼,

자동으로 이름이 입력되길 원하면 입력 탭 등 각 고유의 `XPath` 값을 가져와서 코드에 넣어주면 된다.

 

# 예약 버튼 클릭 (xpath로 지정한 예약 버튼)
reserve_button = driver.find_element(By.XPATH, '예약버튼 XPath 값')
reserve_button.click()

 

 

 

 

 

 

시간 설정하기

 

 

예약은 보통 특정시간을 기준으로 활성화되기 때문에 그전까지 대기 후 특정 시간에 자동실행되게 해야 한다.

 

  • `datetime` 체크하면서 예약 가능한 순간까지 대기
  • 정확한 `XPath` 값으로 예약 버튼 빠르게 클릭
  • `while`, `if` 등 활용해 성공할 때까지 반복 시도

 

키워드  설명
`while` 조건이 참일 때 계속 반복
`if` 조건이 참일 때 특정 코드 실행
`try` 에러가 날 수도 있는 코드 실행
`except` 에러가 발생하면 실행할 코드 지정
`break` 반복문 강제 종료

 

 

 

자정에 새로고침이 되게 해야 하지만, 

실제로 서버시간이 되어 새로고침 명령이 넘어가기까지의 미세한 차이가 있기 때문에 

딱 00시 00분 00초 새로고침이 아닌, 23시 59분 58초 이상이라는 조건으로 수정했다. 

 

 

 

while True:

`while`이 조건이 참일 때 계속 반복하는 거라, 뒤에 true를 붙여주면 무한 반복하는 코드가 된다.

 

 

 

WebDriverWait(driver, 10)

WebDriverWait : 웹 드라이버가 특정 조건을 만족할 때까지 기다리기

(driver) : 실행 중인 웹드라이버 객체 - 크롬, 사파리 등

(10) : 최대 대기시간 (초)

 

= 웹 드라이버가 특정 조건을 만족할 때까지 10초 기다리기. 주로 `.until`과 함께 쓰인다. 

 

 

 

EC

Expected Conditions의 약자. `selenium` 에서 제공하는 모듈로, 웹 요소가 특정 조건을 만족하는지 확인하는 함수 제공.

  • EC.presence_of_element_located : 요소가 존재하는지 확인
  • EC.visibility_of_element_located : 요소가 화면에 보이는지 확인

 

 

try: ~

except Exception as e: 

try 다음 코드를 실행하다가 오류가 발생하면 except 다음 코드를 실행한다. Exception as e 는 변수 `e`에 오류 사항을 저장하겠다는 뜻.

 

 

 

f " {} " 

`f-string` 으로 문자열 앞에 `f`를 붙이면 문자열 안에서 변수를 쓸 수 있다. 변수처리는 중괄호 `{}`

 

 

 

now.strftime('%H:%M:%S')

strftime 은 string format time 의 줄임말로, 날짜와 시간을 문자열(string)로 변환하는 함수. `now.strftime`은 현재의 날짜와 시간을 불러온다는 것이고, 반드시 괄호 안에 원하는 형식을 넣어야 한다. `%m`은 month,  `%M`은 Minute을 나타내니 헷갈리지 말기!

 

 

 

 

완성하면 이렇게 코드가 나온다.

 

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from datetime import datetime
import time
import pytz

# ChromeDriver 경로 설정 (다운로드 폴더에 있는 chromedriver)
service = Service('/ChromeDriver 경로')

# WebDriver에 Service 객체 전달
driver = webdriver.Chrome(service=service)

# 예약 사이트 열기
driver.get('예약 사이트 주소')

# 서울 시간대 설정
seoul_tz = pytz.timezone('Asia/Seoul')


# 예약

while True:
    # 현재 시간을 서울 시간으로 확인
    now = datetime.now(seoul_tz)

   
    # 예약 시도
    if now.hour == 23 and now.minute == 59 and now.second >= 58:
        print("일찍 새로고침!")
        driver.refresh()

        # 페이지가 완전히 새로고침될 때까지 대기
        try:
            # 예약 버튼이 로드될 때까지 기다리기
            reserve_button = WebDriverWait(driver, 10).until(
                EC.element_to_be_clickable((By.XPATH, '예약버튼 XPath'))
            )
            reserve_button.click()
            print("예약 버튼 클릭 완료")

            # 예약 페이지로 넘어갔는지 확인 (페이지 URL 변경 체크)
            WebDriverWait(driver, 10).until(EC.url_changes(driver.current_url))
            print("예약 창으로 넘어갔습니다!")
            break  # 예약 완료 후 반복 종료
        except Exception as e:
            print("예약 버튼 클릭 오류:", e)
            time.sleep(2)  # 2초 후 다시 시도

    # 정해진 시간까지 대기
    print(f"현재 시간: {now.strftime('%H:%M:%S')} - 대기 중...")
    time.sleep(5)  # 5초마다 현재 시간 확인

 

 

 

반응형