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.
Related Articles
- How To Solve Recaptcha V2 Callback Using Api
- Recaptcha V2 Turnstile Same Site Handling
- Recaptcha V2 Callback Mechanism
Next Steps
Monitor auctions reliably — get your CaptchaAI API key and solve reCAPTCHA v2 challenges automatically.
Discussions (0)
Join the conversation
Sign in to share your opinion.
Sign InNo comments yet.