public

  • Download Gist
urbanspoon_reservations.rb
Ruby
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
require 'rubygems'
require 'mechanize'
 
FIRST_NAME = 'FIRST_NAME'
LAST_NAME = 'LAST_NAME'
PHONE = 'PHONE'
EMAIL = 'EMAIL@provider.com'
 
PARTY_SIZE = 2
SCHEDULE_RANGE = { :start_time => '19:00', :end_time => '20:30' }
 
def start_url(restaurant=2086)
return "http://rez.urbanspoon.com/reservation/start/#{restaurant}"
end
 
def to_minutes(time)
hour, minutes = time.split(':')
raise "Malformed time: #{time}. Should be in the HH:MM format." if hour.nil? || minutes.nil?
return (hour.to_i * 60) + minutes.to_i
end
 
url = start_url()
agent = Mechanize.new { |agent|
agent.user_agent_alias = 'Mac Safari'
}
 
# Get the start page
start_page = agent.get(url)
 
# Bail if there are no reservations
exit if start_page.forms.count != 1
 
# Fill in the details for the reservation
start_form = start_page.forms.first
start_form.size = PARTY_SIZE
 
# Verify if the available times are in the allowed range
available_times = start_form.field_with(:name => 'seating_time').options
 
possible_times = available_times.select do |time|
(to_minutes(SCHEDULE_RANGE[:start_time])..to_minutes(SCHEDULE_RANGE[:end_time])).member?(time.value.to_i)
end
 
# Select the first of the possible times for the reservation
start_form.seating_time = possible_times.first
 
# Submit the details and get back the contact form
contact_info_page = start_form.submit
 
# Check for the existence and get the contact form
exit if contact_info_page.forms.count != 1
contact_form = contact_info_page.forms.first
 
# Fill in the contact details
contact_form["user[first_name]"] = FIRST_NAME
contact_form["user[last_name]"] = LAST_NAME
contact_form["user[phone]"] = PHONE
contact_form["user[email]"] = EMAIL
 
# Submit the contact details and get confirmation page
confirmation_page = contact_form.submit
 
# Confirm the reservation
exit if confirmation_page.forms.count != 1
confirmation_form = confirmation_page.forms.first
final_page = confirmation_form.submit
puts "Got reservation for: #{start_form.seating_time}"

This is genius. Awesome job.

Well done. I also wrote (and grabbed) a SBP reservation using phantomjs, but I definitely did not post it because there is zero incentive to share it. :P

http://www.youtube.com/watch?v=A8I9pYCl9AQ

Nice work! Just don't tell anyone else in Chicago, please!

I can't wait to tell Chicago about this!

we have a place that sends out reservations on a web page like that here in Athens,GA. I tried a few times to get a reservation as soon as it came online, but always failed. It isn't a restaurant, but a small once a month table of people. I even tried copy & paste data and it wasn't fast enough. I might try making this work for our site - http://www.thefourcoursemen.com/about/

Great job, here.

Genius idea! If only UrbanSpoon was programmed to be completely botproof... :P

Do you have similar code for OpenTable?

how often did you run this?

I started out by doing it once a minute. That seemed enough to get reservations initially (it was a once a minute crontab).

The new bot that I'm developing does checks every 5 seconds.

Great! It would be interesting powershell script or .NET :-)

So how does this work? Is a cron job constantly running in the background? Is this running locally or on a server?

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.