본문 바로가기
개발

비행기표 조회 자동화

by PilYeooong 2024. 8. 9.

# 배경

제주도민이라 명절때마다 비행기표 예약 전쟁을 겪어야한다.
중간중간 비행기표가 있는지 매번 직접 들어가야 하는 번거로움이 있었다. 비행기표 조회 및 알림을 자동화해두면 명절 혹은 여행 성수기마다 두고두고 쓸 수 있을 것 같아서 파이썬 기반으로 스크립트를 작성해 보았다.

 

# 사용 기술 및 라이브러리

  • Python 3.10
  • Selenium
  • Slack webhook

 

# 코드

아래는 스크립트 일부분이다.

def main():
    while True:
        url = os.getenv('FLIGHT_SCHEDULE_URL')
        webhook_url = os.getenv('SLACK_WEBHOOK_URL')

        try:
            schedules = get_flight_schedules(url)
            if schedules:
                message = "<!channel>\n" + "\n".join([
                    f"*Airline:* {schedule['airline_name']}\n*Departure:* {schedule['departure_time']} - *Arrival:* {schedule['arrival_time']}\n*Fee:* {schedule['fee']}\n"
                    for schedule in schedules
                ])
            else:
                message = "예약 가능 스케줄이 없습니다."

        except Exception as e:
            message = f"Error sending message: {e}\n{traceback.format_exc()}"

        send_slack_webhook(webhook_url, message)
        
        random_number = random.randint(30, 60)
        time.sleep(random_number)
        
# 크롤링 코드 일부
def get_flight_schedules(url):
    driver = get_driver(url)

    try:
        WebDriverWait(driver, 10).until(
            EC.presence_of_element_located((By.CSS_SELECTOR, 'div.scheduleList > div.tblbody > div.scrollArea'))
        )
        
        soup = BeautifulSoup(driver.page_source, 'html.parser')
        
        scroll_area_div = soup.select_one('div.scheduleList > div.tblbody > div.scrollArea')
        if scroll_area_div:
            flight_info_list = []
            items = scroll_area_div.select('li.itemBlock')
            
            for item in items:
                airline_name_element = item.select_one('span.airlineName > span.name')
                flight_time_element = item.select('div.airlineTime .time')
                fee_element = item.select_one('span.fee')

                airline_name = airline_name_element.text.strip() if airline_name_element else None
                departure_time = flight_time_element[0].text.strip() if flight_time_element else None
                arrival_time = flight_time_element[1].text.strip() if flight_time_element else None
                fee = fee_element.text.strip() if fee_element else None
                
                flight_info = {
                    "airline_name": airline_name,
                    "departure_time": departure_time,
                    "arrival_time": arrival_time,
                    "fee": fee
                }

                flight_info_list.append(flight_info)
            
            return flight_info_list
        
    except:
        return []

    finally:
        driver.quit()

 

항공권 조회를 위한 사이트는 '인터파크 투어'를 사용하였고, Heroku를 통해 작성한 스크립트를 돌려두었다.
별도 UI가 없다보니 체크하고자 하는 비행 스케줄의 URL을 환경변수로 받아 처리하는 형태로 작성했다. 추후 다른 비행스케줄을 체크하고자 할 때 코드 변경없이 환경 변수 변경만으로 동작이 수정되도록 해두었다.

 

 

# 정리

실제로 하루 정도 돌려두고 귀성길 비행기표 예매를 하는데 성공을 하였다.

일단 당장 필요한 부분에 대해서만 기능을 추가해두고 쓰고 있는데 좀 더 개선해볼만한 포인트들도 있는듯하다.
- 슬랙 외에 알림 받아볼 수 있는 루트 추가 ex) 카톡 나에게 보내기
- 비행 스케줄 URL 하나만 받는 형태가 아닌 여러개를 받아 여러 스케줄을 한번에 체크할 수 있게끔 하기

 

소스코드: https://github.com/pilyeooong/flight-checker

'개발' 카테고리의 다른 글

RDB에서 인덱스를 사용하지 않는 케이스들  (0) 2024.05.31
스프링과 싱글턴  (0) 2024.05.26
스프링과 SOLID 원칙  (0) 2024.05.21
Kotlin 간단 정리  (0) 2024.04.16