Solve reCAPTCHA 2 in Selenium (Using Python)

How to solve any captcha using Selenium and AntiCaptcha plugin solver. Selenium installation, setup and examples of the API requests to the plugin. Code snippets are written in Python.

This page provides brief information on how to use Selenium and the AntiCaptcha plugin to solve any captcha (including reCAPTCHA v2, reCAPTCHA v3, Funcaptcha, Geetest, and hCaptcha) in automatic mode.
We will step-by-step install Selenium on your device and learn how to connect our plugin to it. Also, we will automatically solve a Recaptcha in the test environment.
For those who don't know, Selenium is a tool for automating browser launching and surfing.

Those already familiar with Selenium can immediately view the captcha solving code example.

Attention! To use the plugin, an Anti-Captcha.com API KEY is required. Thus, this Recaptcha solving method is paid. But it is very low-priced and convenient!

More information about our extension with captcha solving examples can be found on the main page of the AntiCaptcha plugin.

The test code is presented in Python, as it is the most popular language used with Selenium.
This article will provide examples of source code in Python, and understanding requires knowledge of any programming language and minimal experience working with CLI (also known as "command line" or "terminal").

Python Installation

We will be using Python version 3.
There's a lot of information on installing Python on the internet, both text and video. We won't repeat it here, I'll just pass a few links where you can find all the information:
Video instructions for installing Python
Text instructions for installing Python

In general, you need to install the Python interpreter (python) and add it to PATH to be able to launch it from the console using the "python" command.

Python Installation - Notes for Windows

On Windows 10 and newer versions, there's an option to install Python from the Microsoft Store with a single click.

If installing manually, it is recommended to check "Add python.exe to PATH" during installation. This way, you won't have to type the full path to python.exe and pip3.exe each time you run them. PIP is the Python Package Installer, i.e., a package manager for Python libraries, which we will need to install Selenium.

Python Installation - Notes for Linux

After installing on Linux systems, you will have the executable file python3, for Windows it will be python.exe (without the three at the end).

The package manager PIP may not be installed automatically. If that's the case, just install it from your distribution's package manager. For Ubuntu, for example: sudo apt install python3-pip

Selenium and WebDriver Installation

Here it gets a bit more complicated. Besides installing Selenium itself, it's necessary to install a Web Driver for your browser.
It is an intermediate layer between Selenium and the browser. Each browser requires its Web Driver, but we provide an example for Chrome.
There are many guides to installing it on the internet, they are mostly similar, but often confusing.
So, I present my simplified version, hoping it will be useful for beginner hackers.

Selenium Installation under Python

After installing Python, you will have a special Python package manager (an installer for the entire Python library collection) pip3.
It allows you to quickly install the latest version of Selenium with a simple console command (Terminal or Cmd.exe). pip3 install selenium
For Windows, it will look like this: pip3.exe install selenium

Basically, that's it.
You can check the installation by running python3 or python.exe from the command console. And entering in the terminal from selenium import webdriver
If no error appears after executing this command, Selenium is installed correctly. You can exit the Python interpreter, CTRL+D for Linux and CTRL+Z —> Enter for Windows.

On Windows, you might get an error like "pip3.exe not found". It means Python didn't add itself to the PATH variable during installation.
Return to the Python installation step and check the "Add python.exe to PATH" box. Google it if it won't help.

Web Driver Installation

Again, the Web Driver is an additional layer for communicating with the browser.

  • Python uses Selenium as a library, calling its objects and methods.
  • Selenium connects to the Web Driver of a specific indicated browser (Chrome, Firefox, etc.)
  • The Web Driver opens a regular browser like Chrome or Firefox, which we use in everyday life, and translates commands from Selenium into it. Accordingly, the browser itself should be installed by you beforehand (most likely it is already done, as you are reading this page through a browser).

The Web Driver is essentially a file, such as chromedriver for Chrome, or geckodriver for Firefox. It will be connected to the Selenium library upon initialization.
So, in fact, its installation comes down to downloading the file and putting it in the right place.
Don't forget to choose the version of the Web Driver similar to the version of the browser for which you are installing it (just open your Chrome or Firefox browser - depending on which browser you will be using - and check the version there).
For example, for Chrome version 68, you need the driver of the 68th version.

Below are links with more detailed information on its installation:

Installing the chromedriver driver for Chrome Selenium

  • Find out your version of Chrome by copying into the address bar: chrome://settings/help
  • Remember your version of Chrome, in this example, we have version 118:

  • Use the following link to open the Chrome WebDriver download page and download one for your version of Chrome and for your operating system: Chrome for Testing availability

  • Unpack the archive and put the chromedriver file in the folder with your script.

Other Links

Installing geckodriver for Firefox Selenium
Selenium WebDriver · PyPI
Install Web Drivers

The correctness of the installation is verified in the Python interpreter. Launch python3 or python.exe from the console and enter the following:
For Windows: from selenium import webdriver from selenium.webdriver.chrome.service import Service browser = webdriver.Chrome(service=Service('C:\\path\\where\\chromedriver.exe\\downloaded'))
For Linux: from selenium import webdriver from selenium.webdriver.chrome.service import Service browser = webdriver.Chrome(service=Service('/home/path/where/chromedriver/is'))
If no error messages appear and a browser window opens, the installation was successful.

Many tutorials recommend adding the path of the downloaded Web Driver to the PATH variable or simply placing the downloaded driver in one of the PATH directories.
We also recommend this as it avoids having to specify the driver file path in the commands above each time.
Look for ways to do this for different operating systems online if necessary.

Solving the First Captcha in Selenium

We will focus on a specific example, but if you want to, you can familiarize yourself with examples of launching browsers under Selenium using the link below:
Using Selenium with Python for Automated Testing

Initial Setup and Configuration of the Plugin

One important point to note is that the Anti-Captcha.com API KEY is necessary for the plugin to work.
Typically, it is manually set in the plugin options by each of our users. When working through Selenium, this is not possible.

There are two alternative methods for installing the plugin and entering the API KEY. We will consider both options.

Manual Plugin Download and Key Transfer via API Message

First, we need to visit the plugin download page for solving captcha, select the browser we will use for solving the captcha (Chrome, Firefox), and download the corresponding plugin code files.
For Chrome, these will be CRX or ZIP. For Firefox, XPI format, although ZIP may also work, XPI is preferable.
Place the downloaded file in a project directory, later in our script we will specify its full path.

For key installation, use sending API messages to the plugin, specifically the setOptions method.
The acp_api_send_request method in the code below sends such a message.

The code below is annotated in English. Pay attention to the function call get_browser_with_plugin_ready: change the paths to the plugin and chromedriver files there, and also enter your Anti-Captcha API KEY.

# Import the necessary modules from selenium import webdriver from selenium.webdriver.chrome.service import Service from selenium.webdriver.common.by import By from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.support.wait import WebDriverWait import time import json # Method for sending API requests directly to the plugin # For example, to initialize the API key of the anti-captcha.com service, necessary for the plugin to work # Works only on an active HTML page, # in our case on https://antcpt.com/blank.html # requests will not pass on pages like about:blank def acp_api_send_request(driver, message_type, data={}): message = { # always indicates this specific recipient of the API message 'receiver': 'antiCaptchaPlugin', # request type, for example, setOptions 'type': message_type, # merge with additional data **data } # execute JS code on the page # namely, send the message using the standard method window.postMessage return driver.execute_script(""" return window.postMessage({}); """.format(json.dumps(message))) def set_anti_captcha_api_key(browser, api_key: str): # Go to an empty page to execute an API request to the plugin browser.get('https://antcpt.com/blank.html') # Set the anti-captcha.com API key # replace YOUR-ANTI-CAPTCHA-API-KEY with your hexadecimal key, which can be taken here: # https://anti-captcha.com/clients/settings/apisetup acp_api_send_request( browser, 'setOptions', {'options': {'antiCaptchaApiKey': api_key}} ) # Three seconds pause so the plugin can verify the API KEY on the anti-captcha.com side time.sleep(3) def get_browser_with_plugin_ready(plugin_path: str, driver_path: str, api_key: str): # Initiate Chrome options object to be able to connect the extension options = webdriver.ChromeOptions() # Link to the CRX or ZIP file of the plugin we downloaded earlier options.add_extension(plugin_path) # Create a Browser object (Chrome Web Driver) passing the path where the driver file was downloaded browser = webdriver.Chrome( service=Service(driver_path), options=options ) set_anti_captcha_api_key( browser=browser, api_key=api_key ) return browser browser = get_browser_with_plugin_ready( plugin_path='./plugin.zip', driver_path='./chromedriver', # note: on Windows it should end with ".exe"! api_key='REPLACE_WITH_YOUR_ANTI-CAPTCHA_API_KEY' )

See the full examples on our GitHub!

Automatic Download of the Plugin and API KEY Configuration in the Plugin's Config File

To set up the API KEY, the method described in more detail below is used, but in this case, the plugin is automatically downloaded, and the API KEY is also automatically hardcoded into it.

The code below is annotated in English. Note the function call get_browser_with_plugin_ready: change the path to chromedriver, and also enter your Anti-Captcha API KEY.

# Import the necessary modules from selenium import webdriver from selenium.webdriver.chrome.service import Service from selenium.webdriver.common.by import By from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.support.wait import WebDriverWait import os import pathlib import urllib.request import zipfile def prepare_plugin(anti_captcha_api_key: str): current_script_dir = str(pathlib.Path(__file__).parent.resolve()) modified_plugin_path = current_script_dir + '/plugin_hardcoded_api_key.zip' plugin_extract_path = current_script_dir + '/extracted_plugin' # download the plugin url = 'https://antcpt.com/anticaptcha-plugin.zip' filehandle, _ = urllib.request.urlretrieve(url) # unpack it with zipfile.ZipFile(filehandle, "r") as f: f.extractall(path=plugin_extract_path) # set the API key in the configuration file file = pathlib.Path(plugin_extract_path + '/js/config_ac_api_key.js') file.write_text(file.read_text().replace( "antiCapthaPredefinedApiKey = ''", "antiCapthaPredefinedApiKey = '{}'".format(anti_captcha_api_key) )) # repack the plugin directory zip_file = zipfile.ZipFile(modified_plugin_path, 'w', zipfile.ZIP_DEFLATED) for root, dirs, files in os.walk(plugin_extract_path): for file in files: path = os.path.join(root, file) zip_file.write( path, arcname=path.replace(plugin_extract_path, '')) zip_file.close() return modified_plugin_path def get_browser_with_plugin_ready(driver_path: str, api_key: str): # Initiate Chrome options object to be able to connect the extension options = webdriver.ChromeOptions() # To allow Selenium to return control to our code immediately after the page starts loading # otherwise, if some resources take a long time to load on the page, control # won't return for dozens of seconds until the page is fully loaded options.page_load_strategy = 'none' # the plugin is automatically downloaded and your Anti-Captcha key is embedded in it plugin_path = prepare_plugin(api_key) options.add_extension(plugin_path) # Create a Browser object (Chrome Web Driver) passing the path where the driver file was downloaded return webdriver.Chrome( service=Service(driver_path), options=options ) browser = get_browser_with_plugin_ready( driver_path='./chromedriver', # note: on Windows it should end with ".exe"! api_key='REPLACE_WITH_YOUR_ANTI-CAPTCHA_API_KEY' )

See the full examples on our GitHub!

Opening a Page with Authorization Form and Captcha: Solving the Captcha and Submitting the Form

At this stage, you already have a Browser object, obtained by one of the above methods, with the plugin installed and the Anti-Captcha API key entered. Now we open a test authorization form, fill it out and submit the form.

browser.get('https://anti-captcha.com/demo/?page=recaptcha_v2_textarea') # wait until the form loads and the login input field appears WebDriverWait(browser, 5).until(EC.visibility_of_element_located(( By.CSS_SELECTOR, 'input[name=login]' ))) # fill out the form login_input = browser.find_element(By.CSS_SELECTOR, 'input[name=login]') login_input.send_keys('Test login') password_input = browser.find_element(By.CSS_SELECTOR, 'input[name=pass]') password_input.send_keys('Test password') # wait for the captcha to be automatically solved by the plugin and the element .antigate_solver.solved appears on the page WebDriverWait(browser, 120).until(EC.visibility_of_element_located(( By.CSS_SELECTOR, '.antigate_solver.solved' ))) # submit the form browser.find_element(By.CSS_SELECTOR, 'button').click() # to prevent the browser from closing immediately so you can see the result input()

See the full examples on our GitHub!

Create a file with the extension .py, for example, test.py and copy into it the code from the subsection Automatic Download of the Plugin and API KEY Configuration in the Plugin's Config File or from the subsection Manual Plugin Download and Key Transfer via API Message, add the code from the block above at the end of the file and run it using python3 (or python3.exe on Windows), you will visually see the process of filling out the form and solving the captcha:

python3 ./test.py

Using ProxyOn Tasks

If you wish to mark all your captcha-solving tasks as ProxyOn, as described in the documentation for RecaptchaV2Task on anti-captcha.com, you will need to add a few new lines to the setOptions option block. You need to set proxy task settings like solveProxyOnTasks, userProxyProtocol, userProxyServer, userProxyPort, and so on... More information on these can be found in the setOptions section of our plugin's API.
Now our acp_api_send_request method will look as follows:

acp_api_send_request( browser, 'setOptions', { 'options': { 'antiCaptchaApiKey' : 'YOUR-ANTI-CAPTCHA-API-KEY', 'solveProxyOnTasks' : True, # Enable/disable solving ProxyOn tasks 'userProxyProtocol' : 'http', # Proxy type (http, https, socks4, socks5) 'userProxyServer' : '111.111.111.111', # Proxy server address, only *.*.*.* mask allowed 'userProxyPort' : 1111, # Proxy port 'userProxyLogin' : 'user', # Proxy login 'userProxyPassword' : 'password' # Proxy password } } )

See the full examples on our GitHub!

After executing this request, all subsequent tasks will be of the ProxyOn type. Please set only valid proxy settings, otherwise, you will receive a ERROR_PROXY_* response from Anti-Captcha API.

Running Selenium in Headless Mode (Linux Only)

Selenium Chrome can be launched in headless mode out of the box, but unfortunately, extensions (plugins) do not work in this mode, as Chrome does not support automation with plugins. Use the Xvfb utility, which provides a virtual display for your application.

# installing the package apt install -y xvfb # setting the display variable export DISPLAY=:2 # starting the Xvfb server in the background (once) /usr/bin/Xvfb :2 -screen 2 1024x768x24 & # wait a bit to let it start (once) sleep 5 # add the "xvfb-run" prefix to the python script xvfb-run python3 test.py

Explicitly Setting the Anti-Captcha Service Key

By our users' requests, we have implemented an alternative way of specifying the API key — by entering it in the configuration file.
For this, you need to download the plugin code in ZIP format and unpack this archive. Inside, in the js directory, you will find a file config_ac_api_key.js.
Open it in a text editor and enter your anti-captcha.com API key in the variable antiCapthaPredefinedApiKey.
For example:
var antiCapthaPredefinedApiKey = '12345678901234567890123456789012';

Note that in addition to the API KEY, this file also contains the defaultConfig variable, which lists the default values for all plugin options. Feel free to change them at your discretion, the description of each specific option can be peeked at in our plugin's API article, in the setOptions method.
Just keep in mind that in the article, the option names are presented in camelCase, while in the settings file they are with_underscores (useRecaptchaPrecaching ~ use_recaptcha_precaching).

Lastly, repack all the plugin code into a ZIP archive and specify the path to it in the add_extension method (see above our file captcha_solve.py).

Important: the archive should contain the extension files themselves, not the directory they are in. This will prevent the error "cannot process extension #1 from unknown error: cannot read manifest".

And, of course, the lines browser.get('https://antcpt.com/blank.html'), acp_api_send_request(...) and time.sleep(3) are not needed in this case.

We hope this guide has been helpful to you. If you encounter any problems, do not hesitate to contact us at our support service, we will respond!