본문 바로가기
5. 개인 프로젝트 (Personal Projects)/파인 다이닝 가이드 (Fine Dining Guide)

2. Selenium과 Telegram Bot을 활용한 예약 자동화 매크로 개발

by Mojito 2025. 1. 10.

이 글에서는 Selenium과 Telegram Bot을 활용하여 레스토랑 예약 가능 여부를 확인하고, 예약 취소가 발생하면 Telegram을 통해 알림을 보내는 매크로를 개발하는 방법을 안내합니다.


1. 개요

이 매크로는 다음과 같은 기능을 제공합니다:

  • Selenium을 사용하여 레스토랑의 예약 페이지를 자동으로 탐색.
  • 예약 가능한 날짜와 시간을 확인.
  • 예약 취소가 발생하면 Telegram Bot으로 알림 전송.

2. 필요한 사전 설정

(이전 https://mojitos.tistory.com/114 글을 참고 해서 환경 설치를 하셨다면 아래를 건너 뛰셔도 됩니다)

2.1 필수 라이브러리 설치

conda install -c conda-forge selenium
pip install python-telegram-bot

2.2 환경 설정 및 준비


3. 주요 코드

3.1 Telegram 알림 함수

Telegram 알림을 보내는 비동기 함수 telegram_main을 동기적으로 호출하는 간단한 래퍼 함수:

import asyncio
from telegram_bot import main as telegram_main

def send_telegram_message(message: str) -> None:
    """
    Telegram 메시지를 전송하는 동기 함수.
    """
    asyncio.run(telegram_main(message))

3.2 Firefox 브라우저 열기 및 예약 탐색

예약 페이지를 탐색하고 예약 가능 여부를 확인하는 핵심 함수:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.firefox.options import Options as FirefoxOptions

def open_firefox(url: str, headless: bool = False):
    """
    예약 페이지를 탐색하고 예약 가능 여부를 확인.
    """
    options = FirefoxOptions()
    if headless:
        options.add_argument("--headless")
    browser = webdriver.Firefox(options=options)
    short_wait = WebDriverWait(browser, 5)

    try:
        browser.get(url)
        click_reservation_link(browser, short_wait)

        date_labels = [
            "화요일, 1월 14, 2025",
            "수요일, 1월 15, 2025",
            "목요일, 1월 16, 2025",
        ]

        while True:
            for date_label in date_labels:
                if select_date(browser, short_wait, date_label):
                    time_slots = get_available_time_slots(browser, short_wait)
                    if time_slots:
                        send_telegram_message(f"예약 가능: {date_label} {time_slots}")
                        return time_slots

    finally:
        browser.quit()

date_labels 안에 날짜를 형식에 맞춰서 바꿔주시면 원하는 날짜 검색이 가능합니다.

 

3.3 날짜 선택 및 시간 확인

def select_date(browser, wait, date_label):
    """ 특정 날짜를 선택하는 함수. """
    try:
        date_element = wait.until(
            EC.element_to_be_clickable((By.XPATH, f"//div[@aria-label='{date_label}']"))
        )
        date_element.click()
        return True
    except Exception:
        return False

def get_available_time_slots(browser, wait):
    """ 사용 가능한 예약 시간 확인. """
    try:
        time_elements = wait.until(
            EC.presence_of_all_elements_located((By.XPATH, "//span[@class='time']"))
        )
        return {elem.text.strip() for elem in time_elements if elem.text.strip()}
    except Exception:
        return set()

4. 실행 방법

4.1 스크립트 저장 및 실행

  1. 위 코드를 하나의 Python 파일로 저장합니다. (예: reservation_bot.py)
  2. 예약하려는 URL을 설정합니다. (URL 은 캐치테이블에서 원하는 식당의 메인 페이지의 주소를 가져오시면 됩니다)
if __name__ == "__main__":
    url = "https://app.catchtable.co.kr/ct/shop/(식당 고유 이름)?type=DINING" # url은 꼭 type=DINING으로 끝나는 URL 복사 후 사용해주세요.
    open_firefox(url, headless=False)
  1. 명령어를 실행하여 스크립트를 실행합니다:
python reservation_bot.py

5. 주요 기능 설명

  1. 예약 페이지 열기: Selenium WebDriver를 사용해 예약 페이지를 엽니다.
  2. 날짜 및 시간 선택: 지정된 날짜를 탐색하며 예약 가능 여부를 확인합니다.
  3. Telegram 알림: 예약 가능한 슬롯이 발견되면 Telegram을 통해 알림을 전송합니다.

6. 결과물

 

간단하게 빈자리가 생기면 누구보다 빠르게 나에게 알림을 주는 매크로를 만들어 보았습니다. 위 방법으로 원하시는 레스토랑 예약에 조금 더 도움이 되시길 바라며 긴 글 읽어주셔서 감사합니다. 

반응형

댓글