Use Cases

CAPTCHA Handling for Auction Site Monitoring

Auction platforms protect listing data and search functionality with reCAPTCHA v2. CAPTCHAs appear most often during rapid search queries, listing detail views, and bid history lookups. Here's how to maintain reliable monitoring across auction sites.

Where CAPTCHAs Trigger on Auction Sites

Action CAPTCHA type Trigger pattern
Search/browse listings reCAPTCHA v2 Rapid sequential searches
View listing details reCAPTCHA v2 High volume from same IP
Check bid history reCAPTCHA v2 Repeated detail page loads
Category browsing Cloudflare Turnstile Bot-like navigation speed
Price alert pages reCAPTCHA v2 Frequent refreshes

Auction Monitoring with CAPTCHA Solving

import requests
import time
import re
from datetime import datetime

class AuctionMonitor:
    def __init__(self, api_key):
        self.api_key = api_key
        self.session = requests.Session()
        self.session.headers.update({
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
        })

    def search_listings(self, auction_url, query, category=None):
        """Search auction listings, solving CAPTCHAs when triggered."""
        params = {"q": query}
        if category:
            params["category"] = category

        response = self.session.get(
            f"{auction_url}/search", params=params
        )

        if self._has_captcha(response.text):
            site_key = self._extract_site_key(response.text)
            token = self._solve_recaptcha(site_key, f"{auction_url}/search")
            response = self.session.post(
                f"{auction_url}/search",
                data={**params, "g-recaptcha-response": token}
            )

        return self._parse_listings(response.text)

    def monitor_listing(self, auction_url, listing_id):
        """Get current bid and listing details."""
        url = f"{auction_url}/item/{listing_id}"
        response = self.session.get(url)

        if self._has_captcha(response.text):
            site_key = self._extract_site_key(response.text)
            token = self._solve_recaptcha(site_key, url)
            response = self.session.post(url, data={
                "g-recaptcha-response": token
            })

        return self._parse_listing_detail(response.text)

    def track_bids(self, auction_url, listing_ids, interval=60):
        """Track bid changes across multiple listings."""
        history = {lid: [] for lid in listing_ids}

        while True:
            for listing_id in listing_ids:
                try:
                    detail = self.monitor_listing(auction_url, listing_id)
                    previous = history[listing_id]

                    if previous and detail["current_bid"] != previous[-1]["current_bid"]:
                        print(f"Bid change on {listing_id}: "
                              f"${previous[-1]['current_bid']} → ${detail['current_bid']}")

                    history[listing_id].append(detail)
                except Exception as e:
                    print(f"Error checking {listing_id}: {e}")

            time.sleep(interval)

    def _has_captcha(self, html):
        return "g-recaptcha" in html or "recaptcha" in html.lower()

    def _extract_site_key(self, html):
        match = re.search(r'data-sitekey="([^"]+)"', html)
        if match:
            return match.group(1)
        match = re.search(r"sitekey['\"]?\s*[:=]\s*['\"]([^'\"]+)", html)
        if match:
            return match.group(1)
        raise ValueError("Could not find reCAPTCHA site key")

    def _solve_recaptcha(self, site_key, page_url):
        resp = requests.post("https://ocr.captchaai.com/in.php", data={
            "key": self.api_key,
            "method": "userrecaptcha",
            "googlekey": site_key,
            "pageurl": page_url,
            "json": 1
        })
        task_id = resp.json()["request"]

        for _ in range(60):
            time.sleep(3)
            result = requests.get("https://ocr.captchaai.com/res.php", params={
                "key": self.api_key,
                "action": "get",
                "id": task_id,
                "json": 1
            })
            data = result.json()
            if data["status"] == 1:
                return data["request"]

        raise TimeoutError("reCAPTCHA solve timed out")

    def _parse_listings(self, html):
        from bs4 import BeautifulSoup
        soup = BeautifulSoup(html, "html.parser")
        listings = []
        for item in soup.select(".listing-item, .auction-item"):
            listings.append({
                "title": item.select_one(".title")?.text?.strip(),
                "current_bid": item.select_one(".price, .bid")?.text?.strip(),
                "time_left": item.select_one(".time-left")?.text?.strip(),
                "url": item.select_one("a")?.get("href")
            })
        return listings

    def _parse_listing_detail(self, html):
        from bs4 import BeautifulSoup
        soup = BeautifulSoup(html, "html.parser")
        return {
            "title": soup.select_one("h1, .item-title")?.text?.strip(),
            "current_bid": soup.select_one(".current-bid, .price")?.text?.strip(),
            "bid_count": soup.select_one(".bid-count")?.text?.strip(),
            "time_left": soup.select_one(".time-remaining")?.text?.strip(),
            "checked_at": datetime.now().isoformat()
        }

# Usage
monitor = AuctionMonitor("YOUR_API_KEY")
listings = monitor.search_listings(
    "https://auctions.example.com",
    "vintage electronics",
    category="collectibles"
)

Price Alert System (JavaScript)

class AuctionTracker {
  constructor(apiKey) {
    this.apiKey = apiKey;
    this.watchList = new Map();
  }

  addWatch(listingId, url, maxPrice) {
    this.watchList.set(listingId, { url, maxPrice, history: [] });
  }

  async checkAll() {
    const alerts = [];

    for (const [id, watch] of this.watchList) {
      try {
        const detail = await this.fetchListing(watch.url);
        watch.history.push(detail);

        const price = parseFloat(detail.currentBid.replace(/[^0-9.]/g, ''));
        if (price >= watch.maxPrice * 0.9) {
          alerts.push({
            listing: id,
            price,
            threshold: watch.maxPrice,
            message: `Price approaching limit: $${price} / $${watch.maxPrice}`
          });
        }
      } catch (error) {
        alerts.push({ listing: id, error: error.message });
      }
    }

    return alerts;
  }

  async fetchListing(url) {
    const response = await fetch(url);
    const html = await response.text();

    if (html.includes('g-recaptcha')) {
      return this.solveAndFetch(url, html);
    }

    return this.parseDetail(html);
  }

  async solveAndFetch(url, html) {
    const siteKeyMatch = html.match(/data-sitekey="([^"]+)"/);
    if (!siteKeyMatch) throw new Error('No reCAPTCHA site key found');

    const submitResp = await fetch('https://ocr.captchaai.com/in.php', {
      method: 'POST',
      body: new URLSearchParams({
        key: this.apiKey,
        method: 'userrecaptcha',
        googlekey: siteKeyMatch[1],
        pageurl: url,
        json: '1'
      })
    });

    const { request: taskId } = await submitResp.json();

    for (let i = 0; i < 60; i++) {
      await new Promise(r => setTimeout(r, 3000));
      const result = await fetch(
        `https://ocr.captchaai.com/res.php?key=${this.apiKey}&action=get&id=${taskId}&json=1`
      );
      const data = await result.json();
      if (data.status === 1) {
        // Resubmit with token
        const response = await fetch(url, {
          method: 'POST',
          body: new URLSearchParams({ 'g-recaptcha-response': data.request })
        });
        return this.parseDetail(await response.text());
      }
    }

    throw new Error('reCAPTCHA solve timed out');
  }

  parseDetail(html) {
    // Parse auction listing details from HTML
    return {
      currentBid: html.match(/current.?bid[^>]*>([^<]+)/i)?.[1]?.trim(),
      bidCount: html.match(/(\d+)\s*bids?/i)?.[1],
      timeLeft: html.match(/time.?(?:left|remaining)[^>]*>([^<]+)/i)?.[1]?.trim(),
      checkedAt: new Date().toISOString()
    };
  }
}

// Usage
const tracker = new AuctionTracker('YOUR_API_KEY');
tracker.addWatch('item-123', 'https://auctions.example.com/item/123', 500);
tracker.addWatch('item-456', 'https://auctions.example.com/item/456', 200);
const alerts = await tracker.checkAll();

Monitoring Strategy

Check frequency Use case Expected CAPTCHA rate
Every 30 seconds Last-minute bidding High — use proxies
Every 5 minutes Active auction tracking Moderate
Every 15 minutes Watchlist monitoring Low
Every hour Long-term price research Minimal

Reducing CAPTCHA Frequency

Technique Impact
Reuse session cookies Maintains authenticated state
Rotate residential proxies Distributes requests across IPs
Randomize request intervals Avoids periodic detection patterns
Use authenticated accounts Lower CAPTCHA trigger thresholds

Troubleshooting

Issue Cause Fix
CAPTCHA on every request No session persistence Reuse requests.Session()
reCAPTCHA token rejected Token expired (2-min lifetime) Solve just before submission
Listings page shows 0 results CAPTCHA silently filtered results Check for hidden CAPTCHA elements
IP blocked after many CAPTCHAs Rate limit exceeded Rotate proxies, increase intervals

FAQ

How fast can I check auction listings?

CaptchaAI solves reCAPTCHA v2 in 10–30 seconds. For time-sensitive auctions, pre-solve tokens and rotate proxies to minimize delays.

Will auction sites detect monitoring?

Detection depends on request patterns, not CAPTCHA solving. Use realistic intervals, rotate user agents, and avoid scraping during low-traffic hours when your requests stand out.

Can I monitor live auctions in real time?

For the final minutes of an auction, use browser automation with pre-authenticated sessions to minimize CAPTCHA encounters. CaptchaAI's speed handles any CAPTCHAs that still appear.

Next Steps

Monitor auctions reliably — get your CaptchaAI API key and solve reCAPTCHA v2 challenges automatically.

Full Working Code

Complete runnable examples for this article in Python, Node.js, PHP, Go, Java, C#, Ruby, Rust, Kotlin & Bash.

View on GitHub →

Discussions (0)

No comments yet.