Captcha Solver for Web Scraping

Stop captchas from blocking your web scraper. FastCaptcha solves image captchas in 0.3 seconds for $0.33 per 1,000 solves. Integrates with Scrapy, BeautifulSoup, Puppeteer, and any HTTP client.

0.3s
Per Captcha
$0.33
Per 1,000
95%
Accuracy
∞
Concurrency

Captcha Solving in Your Scraping Stack

Ready-to-use code for popular scraping frameworks

requests + BeautifulSoup

import requests
from bs4 import BeautifulSoup
from io import BytesIO

FC_KEY = "YOUR_FASTCAPTCHA_KEY"
session = requests.Session()

def solve_captcha_from_img_tag(soup, session):
    """Extract captcha img src and solve it."""
    captcha_img = soup.find("img", {"class": "captcha"})
    if not captcha_img:
        return None

    img_url = captcha_img.get("src")
    img_data = session.get(img_url).content

    res = requests.post(
        "https://fastcaptcha.org/api/v1/ocr/",
        headers={"X-API-Key": FC_KEY},
        files={"image": ("captcha.png", BytesIO(img_data))}
    )
    return res.json()["text"]

# In your scraping loop
page = session.get("https://example.com/data")
soup = BeautifulSoup(page.text, "html.parser")

captcha_answer = solve_captcha_from_img_tag(soup, session)

# Submit form with captcha answer
session.post("https://example.com/submit", data={
    "captcha": captcha_answer,
    "query": "my search"
})

Scrapy Spider

import scrapy
import requests
from io import BytesIO

class CaptchaSpider(scrapy.Spider):
    name = "captcha_spider"
    FC_KEY = "YOUR_FASTCAPTCHA_KEY"

    def start_requests(self):
        yield scrapy.Request(
            "https://example.com/form",
            callback=self.parse_form
        )

    def parse_form(self, response):
        # Extract captcha image URL
        captcha_url = response.css("img.captcha::attr(src)").get()
        full_url = response.urljoin(captcha_url)

        # Download captcha image
        img_data = requests.get(full_url).content

        # Solve with FastCaptcha (0.3s)
        res = requests.post(
            "https://fastcaptcha.org/api/v1/ocr/",
            headers={"X-API-Key": self.FC_KEY},
            files={"image": ("c.png", BytesIO(img_data))}
        )
        captcha_text = res.json()["text"]

        # Submit form with solution
        yield scrapy.FormRequest.from_response(
            response,
            formdata={"captcha": captcha_text},
            callback=self.parse_results
        )

    def parse_results(self, response):
        # Extract your data here
        yield {"data": response.css(".result").getall()}

Parallel Batch Solving

import requests
from concurrent.futures import ThreadPoolExecutor, as_completed

FC_KEY = "YOUR_FASTCAPTCHA_KEY"

def solve_one(captcha_url):
    """Download and solve a single captcha URL."""
    img = requests.get(captcha_url).content
    res = requests.post(
        "https://fastcaptcha.org/api/v1/ocr/",
        headers={"X-API-Key": FC_KEY},
        files={"image": ("c.png", img)}
    )
    return captcha_url, res.json()["text"]

# Solve 20 captchas in parallel (~0.7s total)
captcha_urls = [
    "https://site.com/captcha/1.png",
    "https://site.com/captcha/2.png",
    # ... up to hundreds
]

results = {}
with ThreadPoolExecutor(max_workers=20) as pool:
    futures = {pool.submit(solve_one, url): url
               for url in captcha_urls}
    for future in as_completed(futures):
        url, text = future.result()
        results[url] = text

print(results)  # {url: "ABC123", ...}

Puppeteer Web Scraper

const puppeteer = require('puppeteer');
const axios = require('axios');
const FormData = require('form-data');

async function scrapeWithCaptcha() {
  const browser = await puppeteer.launch({ headless: true });
  const page = await browser.newPage();

  await page.goto('https://example.com/data');

  // Check if captcha is present
  const captchaEl = await page.$('img.captcha');
  if (captchaEl) {
    // Screenshot the captcha
    const imgBuffer = await captchaEl.screenshot();

    // Solve with FastCaptcha (0.3s)
    const form = new FormData();
    form.append('image', imgBuffer, 'captcha.png');

    const { data } = await axios.post(
      'https://fastcaptcha.org/api/v1/ocr/',
      form,
      { headers: { 'X-API-Key': 'YOUR_KEY', ...form.getHeaders() } }
    );

    // Fill captcha and continue
    await page.type('#captcha-input', data.text);
    await page.click('#submit');
    await page.waitForNavigation();
  }

  // Extract your data
  const results = await page.$$eval('.item', els =>
    els.map(el => el.textContent)
  );

  await browser.close();
  return results;
}

scrapeWithCaptcha().then(console.log);

Captcha Solving Costs for Web Scrapers

The cheapest captcha solving option for high-volume scraping

10K solves/month

$3.30
vs $13.90 with human services

100K solves/month

$33
vs $139 with human services

1M solves/month

$330
vs $1,390 with human services

Stop Captchas from Blocking Your Scraper

100 free credits. No credit card. Integrate in minutes.