How to Automate Image CAPTCHA Solving Using 2Captcha API with Python & Selenium



This content originally appeared on DEV Community and was authored by Victor Maina

CAPTCHAs are a common security measure to prevent bots from accessing websites. While they serve a legitimate purpose, they can be a hurdle for automation tasks. In this guide, we’ll explore how to automate solving image-based CAPTCHAs using the 2Captcha API with Python and Selenium.

Prerequisites
Before we begin, ensure you have:

Python installed (3.6+ recommended)

A 2Captcha API key (Sign up here)

Basic knowledge of Selenium WebDriver

Required Python packages:

bash
pip install selenium requests pillow python-dotenv twocaptcha-python
Step 1: Setting Up the Environment
1.1 Install Required Libraries
bash
pip install selenium requests pillow python-dotenv twocaptcha
1.2 Store API Key in .env
Create a .env file:

env
APIKEY=your_2captcha_api_key_here
1.3 Initialize Selenium WebDriver
python

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager

def create_browser(headless=False):
    options = Options()
    options.add_argument("--disable-blink-features=AutomationControlled")
    options.add_argument("--no-sandbox")
    options.add_argument("--disable-dev-shm-usage")

    if headless:
        options.add_argument("--headless=new")

    driver = webdriver.Chrome(
        service=Service(ChromeDriverManager().install()),
        options=options
    )
    return driver

Step 2: Extracting the CAPTCHA Image
We need to locate the CAPTCHA image and download it for processing.

python

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import base64
import requests

def get_captcha_image(driver):
    try:
        captcha_img = WebDriverWait(driver, 10).until(
            EC.presence_of_element_located((By.XPATH, 
                "//img[contains(@src, 'captcha') or contains(@src, 'code')]"))
        )

        img_src = captcha_img.get_attribute('src')
        if img_src.startswith('data:image'):
            img_data = base64.b64decode(img_src.split(',')[1])
        else:
            img_data = requests.get(img_src).content

        with open('captcha.jpg', 'wb') as f:
            f.write(img_data)

        return 'captcha.jpg'
    except Exception as e:
        print(f"❌ Failed to get CAPTCHA: {str(e)}")
        return None

Step 3: Solving CAPTCHA Using 2Captcha API
Now, we’ll send the CAPTCHA image to 2Captcha and retrieve the solution.

python

from twocaptcha import TwoCaptcha
from dotenv import load_dotenv
import os

load_dotenv()
API_KEY = os.getenv("APIKEY")
solver = TwoCaptcha(API_KEY)

def solve_captcha(image_path):
    try:
        result = solver.normal(image_path, numeric=0, minLen=4, maxLen=6)
        return result['code']
    except Exception as e:
        print(f"❌ CAPTCHA solving failed: {str(e)}")
        return None

Step 4: Submitting the Solved CAPTCHA
Once we have the solution, we fill the input field and submit the form.

python

def submit_captcha_solution(driver, solution):
    try:
        input_field = WebDriverWait(driver, 10).until(
            EC.presence_of_element_located((By.XPATH, 
                "//input[contains(@name, 'captcha') or contains(@id, 'captcha')]"))
        )
        input_field.clear()
        input_field.send_keys(solution)

        submit_button = WebDriverWait(driver, 10).until(
            EC.element_to_be_clickable((By.XPATH, "//button[@type='submit']"))
        )
        submit_button.click()
        return True
    except Exception as e:
        print(f"❌ Failed to submit CAPTCHA: {str(e)}")
        return False

Step 5: Putting It All Together
Now, let’s combine all steps into a single workflow.

python

def automate_captcha_solving(driver, url):
    driver.get(url)

    # Step 1: Get CAPTCHA image
    captcha_image = get_captcha_image(driver)
    if not captcha_image:
        return False

    # Step 2: Solve CAPTCHA
    solution = solve_captcha(captcha_image)
    if not solution:
        return False

    # Step 3: Submit solution
    return submit_captcha_solution(driver, solution)

# Example Usage
if __name__ == "__main__":
    driver = create_browser(headless=False)
    success = automate_captcha_solving(driver, "https://example.com/captcha-page")
    print("✅ CAPTCHA solved successfully!" if success else "❌ Failed to solve CAPTCHA")
    driver.quit()

Common Issues & Fixes

  1. CAPTCHA Not Detected Fix: Adjust the XPath to match the website’s CAPTCHA element.

Example:

python
"//img[contains(@class, 'captcha-img')]"

  1. 2Captcha API Fails Fix: Check your API key balance and ensure the image is clear.

Enhance image quality before sending:

python

from PIL import Image, ImageFilter, ImageEnhance

def enhance_image(image_path):
    img = Image.open(image_path)
    img = img.convert('L')  # Grayscale
    enhancer = ImageEnhance.Contrast(img)
    img = enhancer.enhance(2.0)  # Increase contrast
    img.save('enhanced_captcha.jpg')
    return 'enhanced_captcha.jpg'
  1. Submit Button Not Clickable Fix: Use JavaScript click as a fallback:

python
driver.execute_script("arguments[0].click();", submit_button)

Conclusion
By using 2Captcha API with Selenium, we can automate CAPTCHA solving efficiently. This method is useful for:

Web scraping (where CAPTCHAs block data extraction)

Automated testing (bypassing CAPTCHAs in test environments)

Bot automation (for repetitive tasks requiring login)

Final Thoughts
While automation is powerful, always respect website policies and use this method ethically. Some websites may block automated CAPTCHA-solving attempts, so use it responsibly.


This content originally appeared on DEV Community and was authored by Victor Maina