본문 바로가기

자동화/Selenium

설날 연휴 KTX 좌석 남아있는거 자동화로 확인하기

728x90

지난 추석에 KTX 예매를 실패하여 고속버스를 타고 왔는데 버스로 가도 길이 막혀서 훨씬 오래 걸렸던 기억이 있습니다.

그래서 이번 설날에는 KTX 예매를 꼭 성공하겠다고 했는데 또 시간을 놓쳐서 이미 대부분 예매가 꽉찬걸 확인했습니다 ㅠㅠ

 

 

매번 KTX 좌석 현황을 볼 수 없기에 좀 더 편리하게 자동화로 구현해보면 어떨까 생각해서 시도해보았습니다.

 

네이버 지도웹에 기차시간표를 확인할 수 있어서 필요한 날짜와 경로를 적은 URL을 바로 호출하도록 구현하였습니다.

(저는 설날 연휴 중 1월 23일 광주송정역 -> 용산역으로 가는 경로를 URL로 선택하였습니다.)

 

지도웹 내 기차 탭 열차시간표

 

driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))

# 원하는 경로 및 날짜를 선택한 지도 URL
driver.get('https://map.naver.com/v5/train?trainPath=end-train%2Fbridges%2Fschedule-board%2Fpc%2Fhome%3FdsId=3300140%26asId=3300197%26dsCd=0036%26asCd=0104%26pa=1%26pc=0%26ps=0%26pm=0%26pe=0%26pb=0%26pd=0%26pt=1%26gDt=2023-01-23T00%253A00%253A00%26cDt=%26fc=true%26si=4%26tf=0%26trnDnCd=1%26trnGpCd=109%26trnStCd=015%26selGoOrCome=go%26fromPanelNum=null%26userQuery=&c=14133687.8003187,4513248.8202003,17,0,0,0,dh')

 

원하는 횟수만큼 반복하기 위해 for문으로 작성하였으며 새로고침 후 10초의 대기시간을 추가하였습니다. 

(지도 URL을 호출하고 목록을 띄우는데 시간이 꽤 필요하였기에 여유있게 10초를 주었습니다.)

 

열차시간 조회 화면 코드를 보니 프레임 변경이 필요하여 프레임 변경하는 코드를 추가하였습니다.

 

for i in range(1, 4):
    driver.refresh()

    time.sleep(10)

    # 열차시간 조회 프레임으로 변경
    driver.switch_to.frame('trainScheduleIframe')

    time.sleep(2)

 

저는 KTX만 보기 위해 KTX 항목 선택 코드를 추가하였습니다.

무궁화나 다른 열차도 보고싶은 경우에는 코드를 제외하면 전체탭으로 확인이 가능합니다.

 

전체 시간표를 보기 위해 더보기 횟수만큼 스크롤 내린 후 더보기 버튼을 클릭하는 코드를 추가하였습니다.

제가 선택한 경로에서는 2번의 더보기 횟수로 전체 시간표를 볼 수 있었지만

다른 경로에서는 3번이 필요한 경우도 있어서 3번의 경우에는 range(3)으로 코드를 변경하시면 됩니다.

 

# KTX 항목 선택
driver.find_element(By.ID, 'KTX1').click()

time.sleep(2)

# 더보기 횟수만큼 반복
for k in range(2):
    driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
    driver.find_element(By.CLASS_NAME,
                        '_6dxTh1Q1zE9UbHXa_QSSr._1P5vSNW3ee08t_RWgH66kb._3VYjabEgzpIANKXMhjcH74 ').click()
    time.sleep(2)

 

원하는 데이터들은 find_elements로 한번에 추출하였습니다. 모두 CLASS_NAME으로 구현하였습니다. 

(구현하다보니 CLASS_NAME 들이 되게 복잡하게 되어있는걸로 확인되네요;; ㅎㅎ)

 

# 예약가능 문구 리스트
reserve_list = driver.find_elements(By.CLASS_NAME, 'ot2QGkxOlDSLhgEjj21VN')

# 출발시간 리스트
dtime_list = driver.find_elements(By.CLASS_NAME, '_1zfsnAnzSd66LcKREQZpFI')

# 소요시간 리스트
ltime_list = driver.find_elements(By.CLASS_NAME, '_2QA5YeeURKqAd_lDO4BK6W')

 

모든 데이터의 리스트 수가 똑같기 때문에 하나의 리스트를 for문으로 작성한 후 각각의 데이터를 출력하였습니다.

예약가능 문구 리스트를 확인해보니 일반 좌석과 특석이 줄바꿈으로 나누어져 있는걸로 확인하였습니다.

좀 더 보기 편하게 하기 위해 문자열 replace 기능을 통해 줄바꿈은 띄어쓰기로 변경하여 구현하였습니다.

 

for j in range(len(reserve_list)):
    replace_str = reserve_list[j].text.replace('\n', ' ')
    print(dtime_list[j].text, ltime_list[j].text, replace_str)

 

전체 코드입니다.

좌석이 있는지만 확인할 수 있는 코드라 간단하게 구현되었으며 좀 더 구현할 경우 자동 예매전까지도 가능하지 않을까 생각됩니다. 

 

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


driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))

# 원하는 경로 및 날짜를 선택한 지도 URL
driver.get('https://map.naver.com/v5/train?trainPath=end-train%2Fbridges%2Fschedule-board%2Fpc%2Fhome%3FdsId=3300140%26asId=3300197%26dsCd=0036%26asCd=0104%26pa=1%26pc=0%26ps=0%26pm=0%26pe=0%26pb=0%26pd=0%26pt=1%26gDt=2023-01-23T00%253A00%253A00%26cDt=%26fc=true%26si=4%26tf=0%26trnDnCd=1%26trnGpCd=109%26trnStCd=015%26selGoOrCome=go%26fromPanelNum=null%26userQuery=&c=14133687.8003187,4513248.8202003,17,0,0,0,dh')


for i in range(1, 4):
    driver.refresh()

    time.sleep(10)

    # 열차시간 조회 프레임으로 변경
    driver.switch_to.frame('trainScheduleIframe')

    time.sleep(2)

    # KTX 항목 선택
    driver.find_element(By.ID, 'KTX1').click()

    time.sleep(2)

    # 더보기 횟수만큼 반복
    for k in range(2):
        driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
        driver.find_element(By.CLASS_NAME,
                            '_6dxTh1Q1zE9UbHXa_QSSr._1P5vSNW3ee08t_RWgH66kb._3VYjabEgzpIANKXMhjcH74 ').click()
        time.sleep(2)

    # 예약가능 문구 리스트
    reserve_list = driver.find_elements(By.CLASS_NAME, 'ot2QGkxOlDSLhgEjj21VN')

    # 출발시간 리스트
    dtime_list = driver.find_elements(By.CLASS_NAME, '_1zfsnAnzSd66LcKREQZpFI')

    # 소요시간 리스트
    ltime_list = driver.find_elements(By.CLASS_NAME, '_2QA5YeeURKqAd_lDO4BK6W')

    print('---------------------' + str(i) + '번째------------------------')

    for j in range(len(reserve_list)):
        replace_str = reserve_list[j].text.replace('\n', ' ')
        print(dtime_list[j].text, ltime_list[j].text, replace_str)

driver.close()

 

해당 코드로 얼떨결에 저는 오전 11시 28분 좌석을 발견하여 예매를 성공할 수 있었습니다.

도움이 안될 수도 있지만 예매 못하신 분들은 꼭 예매 성공하시길 바랍니다!

(최근에 실행해보니 이른 오전 기차표가 추가되었네요. 빠르게 타실 수 있는분들은 좋은 좌석인듯 합니다.)

 

 

코드 실행 화면. 시간별로 예매가 가능한지 확인할 수 있습니다.

 

728x90