Scraping Custom License Plate Availability From The CA DMV

Personalized Plate checker

It’s a pain to check if a personalized license plate is available on the CA website:

    • If it’s available, and you don’t necessarily want to buy that plate right then and there, it breaks the process and you have to start from the beginning, entering in your plate, your VIN, choosing your plate, and all of your other info all over again.
    • If it’s not available, after trying 5 or 10 times and all of your wanted plates are taken, most people get frustrated and settle with something that they know will be available because they don’t have all day.

I set out to find a better way to check these in bulk. Specifically, to scrape the California DMV website for available license plates.

That’s when I landed on this guy’s code; it wasn’t working, and it hadn’t been updated in a couple years, but it was 80% completed:
https://github.com/zeke/california-license-plates

It also had a handful of flaws:

  • There were syntax errors regarding the viewport calculation
  • It went way too fast, usually stumbling over itself or not giving the page enough time to load, which broke the script
  • It would frequently erase the first character and type over itself. So you’d end up in a situation where it checks the word “TOAST” but the first letter was erased, so it would search “OAST”. This led to false positives/negatives.
  • It didn’t have proper error/success handling
  • It was inefficient and used too much resources
  • It was single-threaded
  • etc

Still, it had good bones so I used it as a starting off point. I made a number of powerful modifications to it:

  • Multithreading, so I can run many different versions of this at once to speed up giant lists.
  • Added rotating proxy support and a rotating residential proxy; essential so my IP doesn’t get blocked and I can scale the speed.
  • Reusing the open browser windows when a license plate is taken. Going through the entire process from A-Z is only necessary if you get a “Success” since they won’t let you go “Back” in your browser. But if it’s failed, you can keep trying right there on the page. I modified the script accordingly which significantly sped it up. I split this into two functions; one that starts from the very beginning of the process, and one that backspaces 7 times to try again on the current browser window.
  • Intelligent retries. Sometimes the page doens’t fully load, lags out, etc, so now it will retry automatically a few times.
  • Improved success/error handling. Checking different elements for “Success” and “Taken” eliminated the false positives.
  • Replace zeros (0) character with capital o (O). California doesn’t recognize the zero in their license plate availability checker, so I added some logic to swap this out automatically in the code so I don’t have to think about it.
  • Added human-like delays between steps to give it enough time to load and to look more human.
  • Runs silently. It now runs in headless mode so you aren’t seeing a bunch of browser windows open at once.
  • Display the number of results per minute. Why not?
  • Hardened it against critical script-breaking errors for large jobs. If something breaks, it kills the browser instance elegantly and retries with a new one without aborting the entire script.

The first test ran 80-100 license plate checks per minute!

Results all 2

I haven’t tried turning it up to 20 or 30 yet. Both my proxies and my machine are powerful enough so I don’t see why it wouldn’t work. But I’m not in a big rush and I don’t want to throw up any red flags. And 100 checks per minute is not slow by any means.

At a certain point, it made more sense to only show the “Available” plates that the tool found, since there were far more “Taken” ones. I’m running lists of tens of thousands of keywords at once so I don’t really care so much about the unavailable ones. This gave me much nicer results:

I gave it a bigger list and cranked up the multi-threading from 10 to 30 and I’m achieving over 220 results per minute now!

30

Anyway, kind of random, but it was a fun project! Hopefully I find a license plate that I like with this thing.

What People Are Saying:

  1. jc says:

    Any chance you will be releasing this? Or some fee/donation to use?

  2. jp says:

    I’m looking for a license plate and would love to use this? Any chance you can email me instructions? Thanks in advance!

  3. Artarlio Dabney says:

    Would like to obtain a personal lies. Black license plate for Harley Davidson

  4. Phil says:

    Same here, get it going bro

  5. neil says:

    I’m interested in using this! Any plans to make the repo public?

  6. rr says:

    hey, any chance this will be available to the public or any way I can get access to this?

  7. MISSY says:

    if you’re bored and want to play around. I’m looking for a variation of “OOPS I” (yes like the Britney song) and having no luck.
    I have no idea what it is I’m looking at in your article so I can’t try it myself :).

  8. Michael h says:

    Super interested in this to check for personal variations, still running this or have for public beta?

  9. Alex says:

    Could we get the source code?

  10. Alex says:

    Did you post the source code anywhere? If not, could you do so? Would love to use this.

  11. Sean says:

    Was this ever coded? Link?

  12. Rocco says:

    Hi James, this system looks awesome.

    Any chance you will be publishing this, it’s been some time since you made it. I would love to use this as it’s super hard to find a low character word or combo.

    Email me, as I really would love to see your hard work in action! Thanks

Leave a Reply

Copyright 2025, All rights reserved. Yadda yadda.