Update 12/30/2018: I don’t maintain this piece of code, so don’t simply copy-paste-run. This is just served as a way of inspiration
This article only applies to California DMV road test.
Last month my wife wanted to take the behind-the-wheel drive test at DMV. We made an appointment on April 21st but we want to take the test earlier, and we know sometimes people just reschedule for different reasons and sometimes DMV releases new available time slots. As I believe in DRY principle I don’t want to sit in front of a computer and refresh the page forever to get a lucky chance. And the simple job should be easily done by some quick-and-dirty script.
I googled for such script, didn’t find a perfect script which just meets my needs but I found a script on Github for field office visit appointment. So, based on that, I simply changed the script to adapt to the behind-the-wheel test procedure, added “start date” so that we don’t make too early appointment, keep refreshing until we can get a better time. And we did.
Script can be found at my gist page and here is the no-more-maintained code:
import mechanize from bs4 import BeautifulSoup from datetime import datetime import random import time TGT_DATE = 'April 21, 2015' #i.e. 'September 30, 2014' OFFICE_ID = '548' # officeid for RWC DMV. See HTML code for other office ids TASK = 'DT' form_url = 'https://www.dmv.ca.gov/wasapp/foa/findDriveTest.do' def schedule(targetDate,name,officeId,telNumber,birthday,dlNumber,fromDate=None): tels = telNumber.split('-') births = birthday.split('-') names = name.split(' ') if not fromDate: fromDate = datetime.today() from_date = datetime.today().strftime("%B %d, %Y") else: from_date = datetime.strptime(fromDate,'%B %d, %Y') tgt_date = datetime.strptime(targetDate,'%B %d, %Y') # Browser br = mechanize.Browser() br.open(form_url) br.select_form(name="ApptForm") br['officeId']=[officeId] br.find_control(name="requestedTask").value = ["DT"] br['firstName'] = names br['lastName'] = names br['telArea'] = tels br['telPrefix'] = tels br['telSuffix'] = tels br['dlNumber'] = dlNumber br['birthMonth'] = births br['birthDay'] = births br['birthYear'] = births result = br.submit() result_html = br.response().read() soup = BeautifulSoup(result_html) results = soup.findAll('p',class_="alert") logString = "" for result in results: if ('2015' in result.get_text()): appt_text = result.get_text() logString += "Earliest Appointment found is %s" %(appt_text) appt_date = datetime.strptime(appt_text,'%A, %B %d, %Y at %I:%M %p') if appt_date <= tgt_date and appt_date>=from_date: logString+= "\nCongratulations! You've found a date earlier than your target. Scheduling the appointment..." br.select_form(nr=4) r = br.submit() logString+= "\nConfirming the appointment..." br.select_form(nr=4) r = br.submit() s = BeautifulSoup(br.response().read()) logString += "\nThe final step is to actually schedule it...Use it when necessary.\n" br.select_form(nr=4) r = br.submit() s = BeautifulSoup(br.response().read()) print s # logString += br #print out relevant info related to the appointment print logString with open("test.txt", "a") as myfile: myfile.write(logString) return True else: logString += "\nSorry there is no appointment available between date %s and %s"%(from_date,targetDate) logString += "\n" print logString with open("test.txt", "a") as myfile: myfile.write(logString) return False while not schedule(TGT_DATE,'FIRST LAST',OFFICE_ID,'111-222-3333','01-30-1980','DL00001','April 13, 2015'): waitTime = random.randint(60,600) time.sleep(waitTime)
DMV office’s ID can be found at DMV’s own website, if you need to schedule at another place, please go there and find it. Or you may want to enhance the code if you want try more than one DMV offices at the same time.
Now she happily passed the test so I can open-source the code, and I can’t test it any more because DMV won’t let someone who already passed the test to make such appointment.
This work is licensed under a Creative Commons Attribution-NonCommercial 4.0 International License