이제 내가 원하는 모든 열차표를 확인했으면 조회하기를 누르고 이어서 내 눈에는 당장 안보이지만 홈페이지에 쭉 열차편이 나오겠지요. 그리고 어떤 열차편이 몇시에 있고 또 예매 가능 현황을 확인해서 다시 텔레그램으로 저에가 알려줘야 합니다. 

이제 일방향이 아닌 양방향 소통이 필요한 단계입니다.

(뭐 어렵다기보단 제가 삽질을 많이해서..^^;)

 

사실 이부분은 제가 실력이 없어서 분명 다른 더 나은 방법이 있을 수 있지만 저는 다음과 같은 방법으로 성공했기 때문에 그렇게 이해해 주시기 바랍니다.^^ (저에게 가르침을 주시는 분은 언제나 환영입니다.)

 

1. telegram.py

1
2
3
4
5
6
7
        if tel_text == "검색":              #검색
            self.korail.search_seats()
 
        if tel_text == "결과":
            self.token = "telegram 토큰값"
            self.bot = telepot.Bot(self.token)
            self.bot.sendMessage(chat_id, info)
cs

텔레그램쪽은 단순합니다. 제가 텔레그램에 "검색" 메세지를 입력하면 korail.py의 korail.search_seats() 함수를 수행합니다.

 

그리고 다음 "결과"는 제가 입력하는 것이 아닌 korail.py에서 열차편을 확인한 후 열차 정보와 함께 "결과"라는 텔레그램 메세지를 챗봇에게 보내주는 것입니다. 이경우에 다시 텔레그램 봇을 활성화 해주는 __init__()에서 해준 작업을 다시 수행해야 합니다. korail.py에서 넘어오는 작업이기 때문에 그런가보다 하는데 아직 클래스 및 함수에 대한 완벽한 이해가 부족하여 이해바랍니다.^^; 유추하실 수 있듯이 맨 마지막 info는 korail.py에서 모든 열차정보를 모아 텍스트(str)로 만든 변수 입니다. def start_telegram(self, msg, info=None): 에서 마지막 세번째 info에 대한 정보를 받는 것이지요!

2. korail.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
    def search_seats(self):
        self.driver.find_element_by_css_selector(".btn_inq > a:nth-child(1) > img:nth-child(1)").click()
        time.sleep(2)
        schedule_list = []
        for order_no in range(111):
            try:
                schedule_list.append(str(order_no))
                schedule_list.append(self.driver.find_element_by_xpath("/html/body/div[1]/div[3]/div/div[1]/form[1]/div/div[4]/table[1]/tbody/tr[%s]/td[3]" % order_no).text)
                schedule_list.append(self.driver.find_element_by_xpath("/html/body/div[1]/div[3]/div/div[1]/form[1]/div/div[4]/table[1]/tbody/tr[%s]/td[4]" % order_no).text)
                schedule_list.append(self.driver.find_element_by_xpath("/html/body/div[1]/div[3]/div/div[1]/form[1]/div/div[4]/table[1]/tbody/tr[%s]/td[6]//img" % order_no).get_attribute('alt'))
                schedule_list.append("------------")
                print(schedule_list)
            except:
                schedule_list.append("기차편없음")
                schedule_list.append("------------")
        full_information = '\n'.join(schedule_list)
 
        departure_hour_min_msg = {'from':{'id': id직접입력},'text':'결과'}
        from tele.telegram import Telegram
        Telegram.start_telegram(self, departure_hour_min_msg, full_information)
cs

조회하기를 누르면 위의 10개 교통편이 순차적으로 보입니다.

간단히 우리가 해야 할 작업을 순서를 보면,

1) 조회하기 버튼 누르기

2) 10개의 열차편에 대해서 각각 출발역/시간, 도착역/시간, 일반실예매 이 세가지 정보를 전부 저장하기

3) 텔레그램 챗봇에 "결과"라는 text와 함께 열차정보 보내주기

 

self.driver.find_element_by_css_selector(".btn_inq > a:nth-child(1) > img:nth-child(1)").click()

time.sleep(2)

: 조회하기 버튼을 누르고 창이 뜨기까지 2초정도 기다려 줍니다.

schedule_list = []

: 열차정보를 순차적으로 저장해주기 위하여 빈 리스트를 만듭니다.

 

for order_no in range(1, 10):

    try:

        schedule_list.append(str(order_no))......

: 10개의 열차편을 저장해야 합니다만 저녁 늦은 시간에는 당일 열차편이 10개 이하가 되고 하나도 없는 경우가 있습니다. 그래서 for 문으로 10개 열차편을 순차적으로 검색하고 try, except 구문을 사용하여 열차편이 없는 경우에는 "기차편 없음"으로 대체하게 해 줍니다.

 

코드를 보시면 아시듯이 각 find_element_by_xpath를 이용하면 각 열차편의 원하는 정보는 중간의 tr값만 다르기 때문에 위와 같이 코드를 작성하였습니다. %s 값만 1부터 10까지 변하는 것이지요.

 

full_information = '\n'.join(schedule_list)

: 결국 모든 정보를 담은 리스트를 텍스트(str)로 만들고 이는 예를 들어 다음과 같이 저장됩니다.

1
서울
05:15
부산
07:51
예약하기
------------
2
서울
05:30
부산
08:17
예약하기
------------
3
서울
05:56
부산
11:29
예약하기
------------
 위와 같은 식으로 10번째 열차편까지 보여줍니다.

 

departure_hour_min_msg = {'chat':{'id':실제 chat id 입력 숫자 10자리},'text':'결과'}

: 그리고 텔레그램에 정보를 전달하기 위하여 '결과'라는 단어를 텔레그램에서 잘 받을 수 있도록 위와 같이 딕셔녀리 형태로 만들어 줍니다. 

 

from tele.telegram import Telegram

Telegram.start_telegram(self, departure_hour_min_msg, full_information)

: 그리고 여기서 또 한참을 막혔었는데 다시 korail.py 에서 telegram.py로 넘어가기 위해서는 telegram.py의 Telegram() 클래스를 import해야 합니다만 위 구문을 통상 그러듯이 맨 위로 놓게 되면 순환참조 에러에 직면하게 됩니다. 이미 telegram.py가 korail.py를 import했는데 korail.py가 다시 telegram.py를 import 하게되면 무한히 돌게 되기 때문에 실제 넘어갈 때 import하라고 stack overflow에서 그러더군요...

 

그리고 telegram.py의 start_telegram() 함수로 첫번째 '결과' 메세지 정보 인수와 함께 열차 정보 인수를 넘깁니다.

 

그리고 telegram.py의 start_telegram()에서 위 정보를 받아서 대화창에 열차정보를 보여줍니다.

목차

Python, Telegram으로 KTX 열차표 예매하기(#1 준비)
Python, Telegram으로 KTX 열차표 예매하기(#2 __init__.py)
Python, Telegram으로 KTX 열차표 예매하기(#3 telegram.py, korail.py)
Python, Telegram으로 KTX 열차표 예매하기(#4 텔레그램봇 만들기)

Python, Telegram으로 KTX 열차표 예매하기(#5 telegram, telepot)
Python, Telegram으로 KTX 열차표 예매하기(#6 selenium, 웹 자동화)
Python, Telegram으로 KTX 열차표 예매하기(#7 selenium, regular expression)
Python, Telegram으로 KTX 열차표 예매하기(#8 열차표 확인하기)
Python, Telegram으로 KTX 열차표 예매하기(#9 예매하기)
Python, Telegram으로 KTX 열차표 예매하기(#10 마무리)

+ Recent posts