Python Web Scraper for Automatic Ski Reservations

Develop a Python program to detect when an open reservation is available, and immediately book the reservation for the user

Goals and Requirements

  • Be able to ski and snowboard in the 2020-2021 season

  • Use for any date at a variety of partner resorts

  • Automatically detect when a reservation for a given date opens due to a cancellation

  • Automatically book the reservation and notify that it is booked

Background

  • As mountains were beginning to open in late 2020, most COVID-19 restrictions were still in place and reduced the capacity for many of the ski resorts. Poorly planned reservation systems made it extremely difficult to get any reservations at local resorts or partner resorts across the country on any day.

  • Reserving any date essentially required constantly refreshing the resort page, clicking through menus to enter information and check the specific date, and if one became available then continue through more menus to reserve.

  • This consistently took anywhere from 20 minutes to an hour or so to successfully find an opening. Once found, sometimes the reservation steps took long enough for the spot to no longer be available and the reservation would fail.




Design Process

Main HTML requests to be emulated

  • Check availability of desired dates at desired resort

  • Submit a reservation request

  • Check if reservation is confirmed in user account


Each user has specific info to be included in each request

    • User ID number (found with Inspect after login)

    • phone number

    • email


To be included in each HTML requests

  • User-specific information

  • Main URL for each of the three requests

  • Date range

  • SessionID to extracted from the cookies

  • "Resort Code" for the specific partner resort

  • Desired date

    • __requestverificationtoken

      • Simple method of handling the authentication process for proof-of-concept prototype

      • Copied from a specific HMTL request in DevTools after logging in


Front End User Process

Initial one-time setup

    • Enter phone number

    • Enter email

    • Enter user ID number

    • Use terminal to get ChromeKey for importing and deciphering cookies


Each session

    • Enter desired resort name

      • Select from the resorts with Resort Codes defined in the script

    • Enter "Dates_To_Book" as a list of strings in "mm-dd" format

    • Login to account in Chrome browser

    • Copy "__requestverificationtoken" from the specific header

    • Run Script and wait for confirmation in the terminal


Back End

Setup

    • Import, decipher, and parse cookies from current session given the main URL

    • Insert "__requestverificationtoken" from user input

    • Extract SessionID to include in encoded URL

    • Reformat each user-entered date in the list to the full length


Main Loop

  • For each date in the list of desired dates

  • Send availability check request

  • Interpret json.response

    • Error handling

    • If the day is unavailable, it will be included in 'NoInventoryDays'

  • If date is available

    • Submit reservation HTML request

    • Submit Confirmation HTML request

      • If confirmation request fails, retry loop

    • Remove date from the desired list

  • Loop every few seconds until the desired date list is empty


Error Handling

  • Check json response for specific text involving errors that commonly occurred

  • The reservation system was occasionally unavailable

    • Ignore and continue loop, usually re-opens very shortly

  • Javascript error or "page down" error

    • Indicates that the current session expired, requiring an update to the __requestverificationtoken and/or Session_ID


Summary

Overall the program was very successful. I was able to confirm reservations on any day with minimal effort, and was able to book at partner resorts throughout the country. Occasionally it would still take 20-30 minutes to confirm a spot on busy weekends, but no manual work was required past the initial setup or the occasional restart if the session expired. The intent was never to distribute any further than those around me that I would take trips with, so I did not develop a GUI or a more user-friendly method since the proof-of-concept was more than enough for the end goal.