โ Free credits
โ Priority access
โ Early features
In this tutorial, you'll learn how to solve Google reCAPTCHA puzzles using Python completely free โ
- No third-party services.
- No CAPTCHA-solving services.
- Just you, your code, and a little help from me. ๐ค๐ป We will test on this demo [ https://www.google.com/recaptcha/api2/demo ], so let's get started!
First, let's create a new directory to hold all our project files. Open your terminal or command prompt and run:
mkdir recaptcha-test
Then navigate into the directory:
cd recaptcha-test
๐ Example:
_recaptcha-test__โโโfeel free to name it whatever you like!_
We'll use uv to manage our project. It's a fast Python package manager that handles virtual environments automatically. ๐โก you can learn more about here.
First, make sure you're inside the recaptcha-test directory we created:
cd recaptcha-test
Now, initialize a new Python project:
uv init
This command creates a pyproject.toml file and sets up a virtual environment for youโ. โno extra steps needed! ๐
๐ Note: If you prefer using pip, you can create a virtual environment manually with:
_python -m venv venv_
But I recommend
_uv_โโit's fast and simple. For more details, check out the uv getting started guide.
We'll need a Python package called SeleniumBase to interact with the reCAPTCHA puzzle. In your terminal, run:
uv add seleniumbase
This command installs the package and automatically updates your pyproject.toml and uv.lock files. โก
You'll also need Playwright for browser automation:
uv add playwright
We'll be using Chromium instead of Chrome for this tutorial. I'll explain why Chromium is preferred laterโ, but trust me, it makes a difference! ๐
Download and install Chromium from the official source: ๐ Download Chromium
Quick download steps:
- Go to the Chromium snapshots directory
- Choose your platform: Mac, Win, or Linux ๐ฅ๏ธ
- Open the
LAST_CHANGEfile to find the latest build number - Download the zip file for that build number
After installation is complete, activate the virtual environment:
๐ง Linux / macOS:
source .venv/bin/activate
๐ช Windows (Command Prompt):
.venv\Scripts\activate
๐ช Windows (PowerShell):
.venv\Scripts\Activate.ps1
You'll know it's working when you see (.venv) appear at the beginning of your terminal prompt.
Your folder structure should now look like this:
drwxr-xr-x - dxbear 22 Mar 14:29 ๐ .
drwxr-xr-x - dxbear 22 Mar 14:28 ๐ ..
drwxr-xr-x - dxbear 22 Mar 14:28 ๐ .git
drwxr-xr-x - dxbear 22 Mar 14:30 ๐ .venv
.rw-r--r-- 109 dxbear 22 Mar 14:28 ๐ .gitignore
.rw-r--r-- 5 dxbear 22 Mar 14:28 ๐ .python-version
.rw-r--r-- 92 dxbear 22 Mar 14:28 ๐ main.py
.rw-r--r-- 256 dxbear 22 Mar 14:30 โ๏ธ pyproject.toml โฌ
๏ธ Updated with SeleniumBase
.rw-r--r-- 0 dxbear 22 Mar 14:28 ๐ README.md
.rw-r--r-- 115k dxbear 22 Mar 14:30 ๐ uv.lock โฌ
๏ธ Updated with locked versions
โ SeleniumBase and its dependencies are now ready to use!
Let's open main.py in our project and start coding step by step. ๐
First, we need to import the necessary packages from SeleniumBase and Playwright:
from seleniumbase import cdp_driver
from playwright.async_api import async_playwright
We'll also need asyncio to run our code asynchronously. This step is optionalโโโyou can use synchronous code if you prefer, but async gives us better performance! โก
import asyncio
The cdp_driver from SeleniumBase is a stealth driver that emulates human browser behavior. ๐ต๏ธโโ๏ธ
Unlike regular Playwrightโ where bots are easily detectedโ, โSeleniumBase patches the Playwright browser to bypass bot detection. This is crucial for solving reCAPTCHA, as Google is very good at identifying automated scripts. It's still not enough to bypass reCAPTCHA on its own, but we'll explain how to handle that. What's important first is not triggering bot detection in the first place.
๐ Key Insight: Standard Playwright can be flagged as a bot almost immediately. The
cdp_drivermakes your browser appear as a real human user, giving us a much higher success rate with reCAPTCHA
Inside our main function, we'll start by initializing the CDP driver:
async def main():
# Start the stealth CDP driver
driver = await cdp_driver.start_async()
endpoint_url = driver.get_endpoint_url()
Now we'll connect to the browser using CDP. This is a powerful protocol for web scraping and browser automation! ๐ฏ
async def main():
# Start the stealth CDP driver
driver = await cdp_driver.start_async()
endpoint_url = driver.get_endpoint_url()
# Connect to the browser using CDP (Chrome DevTools Protocol)
async with async_playwright() as p:
browser = await p.chromium.connect_over_cdp(endpoint_url)
context = browser.contexts[0] # Create browser context
page = context.pages[0] # Create page object
# Navigate to Google's official reCAPTCHA demo page
await page.goto("https://www.google.com/recaptcha/api2/demo")
# Wait 10 seconds to observe the page before closing
await driver.sleep(10)
if __name__ == "__main__":
loop = asyncio.new_event_loop()
loop.run_until_complete(main())
BenefitDetails๐ฅท Stealth Mode CDP interacts directly with the browser at the protocol level, making it much harder for services like reCAPTCHA to detect automation.๐ฎ Fine-Grained Control Intercept network requests, manipulate the DOM, capture performance metrics, and simulate network conditionsโ. โall through a single protocol.๐ฆ No Extra Dependencies Unlike Selenium, CDP doesn't require separate browser drivers that need version matching and constant updates.โก Async Support CDP works beautifully with async/await patterns, making your scraping scripts faster and more efficient.๐ค True Browser Emulation Since we're connecting to an actual Chromium instance via CDP, we inherit all browser features without the "tells" that give away automation tools.
- Starts a stealth CDP driver ๐ต๏ธโโ๏ธโโโThe
cdp_driverlaunches a Chromium browser with stealth patches to avoid bot detection. - Connects via CDP ๐โโโWe connect Playwright to the same browser instance using Chrome DevTools Protocol.
- Creates browser context and page ๐โโโWe access the existing browser context and page (or create new ones if needed).
- Navigates to the reCAPTCHA demo page ๐โโโGoogle provides an official demo page for testing: ๐ https://www.google.com/recaptcha/api2/demo
- Waits 10 seconds โฑ๏ธโโโThis gives us time to see the page and reCAPTCHA widget before the browser closes.
import asyncio
from seleniumbase import cdp_driver
from playwright.async_api import async_playwright
async def main():
# Start the stealth CDP driver
driver = await cdp_driver.start_async()
endpoint_url = driver.get_endpoint_url()
# Connect to the browser using CDP (Chrome DevTools Protocol)
async with async_playwright() as p:
browser = await p.chromium.connect_over_cdp(endpoint_url)
context = browser.contexts[0] # Create browser context
page = context.pages[0] # Create page object
# Navigate to Google's official reCAPTCHA demo page
await page.goto("https://www.google.com/recaptcha/api2/demo")
# Wait 10 seconds to observe the page before closing
await driver.sleep(10)
if __name__ == "__main__":
loop = asyncio.new_event_loop()
loop.run_until_complete(main())
If you run this code:
uv run main.py
You'll notice two things:
- It loads and opens Chrome by default ๐โโโ> If Chrome is installed, it will use it. If not, it will ask you to install it.
- We haven't solved any CAPTCHA yet โโโโ> The reCAPTCHA puzzle remains untouched; we just opened the page!
Here's the key insight you must understand: ๐ง
SeleniumBase itself has no capability to bypass or solve Google reCAPTCHA. So we'll use a Chrome extension that does the heavy lifting for us!
To load any extension, you MUST use Chromium, not Chrome. Why? Because Chrome no longer allows loading external extensions in automated environments. Chromium gives us the freedom to load custom extensions without restrictions. This is why I had you install Chromium earlier! ๐ฏ
We'll load a modified version of a Chrome extension called reCAPTCHA solver.
By "modified," I mean I've tweaked it to run automatically as soon as the page loadsโโโso you don't have to click anything to activate it. โจ
๐ฌ How It Works:
The extension uses tiny AI models trained to:
- Detect image-based CAPTCHA challenges ๐
- Identify objects like traffic lights, buses, crosswalks, etc. ๐ฆ๐๐ถ
- Automatically solve the puzzles for you โก
First, let's create a folder to hold our Chrome extension:
mkdir chrome-extensions
Or create it manually in your project directory. ๐
Head over to my GitHub repository to download the extension: ๐ [ https://github.com/dx-bear/reCAPTCHA-solver ] You have two options:
Option 1โโโDownload the extension only ๐ฆ
Look for the recaptcha-solver folder in the repository and download it directly.
Option 2โโโClone the entire repository ๐
git clone [your-repo-url]
Then copy the extension folder into your chrome-extensions directory.
recaptcha-test/
โโโ .venv/
โโโ chrome-extensions/ ๐ New folder
โ โโโ recaptcha-solver/ ๐ Extension files
โ โโโ manifest.json
โ โโโ background.js
โ โโโ ... (other extension files)
โโโ .gitignore
โโโ .python-version
โโโ main.py
โโโ pyproject.toml
โโโ README.md
โโโ uv.lock
Now let's modify main.py to load the reCAPTCHA solver extension into Chromium. ๐ฏ
First, import os to handle file paths:
import os
import asyncio
from seleniumbase import cdp_driver
from playwright.async_api import async_playwright
Now, set the absolute path to our extension and configure the driver:
async def main():
# Get the absolute path to the extension folder
ext = os.path.abspath("./chrome-extensions/recaptcha-solver/0.1.0_0/")
# Start the stealth CDP driver with Chromium and the extension loaded
driver = await cdp_driver.start_async(
use_chromium=True, # Use Chromium instead of Chrome
extension_dir=ext, # Load our custom extension
)
endpoint_url = driver.get_endpoint_url()
# Connect to the browser using CDP
async with async_playwright() as p:
browser = await p.chromium.connect_over_cdp(endpoint_url)
context = browser.contexts[0]
page = context.pages[0]
# Navigate to Google's reCAPTCHA demo page
await page.goto("https://www.google.com/recaptcha/api2/demo")
# Wait for the extension to do its magic! โจ
await driver.sleep(10)
if __name__ == "__main__":
loop = asyncio.new_event_loop()
loop.run_until_complete(main())
Parameter Purpose use_chromium=TrueTells SeleniumBase to launch Chromium instead of Chrome ๐งฉextension_dir=ext Loads our modified reCAPTCHA solver extension into the browser ๐os.path.abspath() Converts the relative path to an absolute path so the browser can find it ๐
When you run the script:
uv run main.py
Here's what will happen:
- First RunโโโDownloading Files ๐ฅโโโThe extension may take a few seconds to download some AI model files. These will be saved in a folder called
downloaded_filesin the same directory. This only happens once! - Chromium Launches ๐โโโA Chromium browser window will open automatically with our extension pre-loaded.
- Page Loads ๐โโโThe script navigates to Google's reCAPTCHA demo page.
- Automatic Solving โจโโโHere's the magicโโโyou'll see the reCAPTCHA widget open and solve itself automatically! No clicking, no manual interaction needed.