Casos de Uso

Manejo de CAPTCHA para el monitoreo del sitio de subastas

Las plataformas de subastas protegen los datos de los listados y la funcionalidad de búsqueda con reCAPTCHA v2. Los CAPTCHA aparecen con mayor frecuencia durante consultas de búsqueda rápida, vistas detalladas de listados y búsquedas del historial de ofertas. A continuación se explica cómo mantener un seguimiento fiable en todos los sitios de subastas.

Dónde se activan los CAPTCHA en los sitios de subastas

Acción Tipo CAPTCHA Patrón de disparo
Buscar listados de /browse reCAPTCHA v2 Búsquedas secuenciales rápidas
Ver detalles del listado reCAPTCHA v2 Alto volumen desde la misma IP
Consultar el historial de ofertas reCAPTCHA v2 Cargas repetidas de la página de detalles
Navegación por categorías Cloudflare Turnstile Velocidad de navegación similar a la de un bot
Páginas de alerta de precios reCAPTCHA v2 Actualizaciones frecuentes

Monitoreo de subastas con resolución CAPTCHA

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")

        def text_or_none(node):
            return node.text.strip() if node and node.text else None

        def attr_or_none(node, attr):
            return node.get(attr) if node else None

        listings = []
        for item in soup.select(".listing-item, .auction-item"):
            listings.append({
          "title": text_or_none(item.select_one(".title")),
          "current_bid": text_or_none(item.select_one(".price, .bid")),
          "time_left": text_or_none(item.select_one(".time-left")),
          "url": attr_or_none(item.select_one("a"), "href")
            })
        return listings

    def _parse_listing_detail(self, html):
        from bs4 import BeautifulSoup
        soup = BeautifulSoup(html, "html.parser")

        def text_or_none(node):
            return node.text.strip() if node and node.text else None

        return {
        "title": text_or_none(soup.select_one("h1, .item-title")),
        "current_bid": text_or_none(soup.select_one(".current-bid, .price")),
        "bid_count": text_or_none(soup.select_one(".bid-count")),
        "time_left": text_or_none(soup.select_one(".time-remaining")),
            "checked_at": datetime.now().isoformat()
        }

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

Sistema de Alerta de Precios (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();

Estrategia de seguimiento

Verificar frecuencia Caso de uso Tasa CAPTCHA esperada
Cada 30 segundos Ofertas de última hora Alto: usar proxies
Cada 5 minutos Seguimiento activo de subastas Moderado
Cada 15 minutos Monitoreo de lista de vigilancia Bajo
Cada hora Investigación de precios a largo plazo Mínimo

Reducir la frecuencia de CAPTCHA

Técnica Impacto
Reutilizar cookies de sesión Mantiene el estado autenticado
Rotar proxies residenciales Distribuye solicitudes entre IPs
Aleatorizar los intervalos de solicitud Evita patrones de detección periódicos
Utilice cuentas autenticadas Umbrales de activación de CAPTCHA más bajos

Solución de problemas

Problema Causa Solución
CAPTCHA en cada solicitud Sin persistencia de sesión Reutilizar requests.Session()
token reCAPTCHA rechazado Token caducado (vida útil de 2 minutos) Resolver justo antes del envío.
La página de listados muestra 0 resultados CAPTCHA resultados filtrados silenciosamente Compruebe si hay elementos CAPTCHA ocultos
IP bloqueada después de muchos CAPTCHA Límite de tarifa excedido Rotar proxies, aumentar intervalos

Preguntas frecuentes

¿Qué tan rápido puedo consultar los listados de subastas?

CaptchaAI resuelve reCAPTCHA v2 en 10 a 30 segundos. Para subastas urgentes, resuelva previamente los tokens y rote los proxies para minimizar los retrasos.

¿Los sitios de subastas detectarán el seguimiento?

La detección depende de los patrones de solicitud, no de la resolución de CAPTCHA. Utilice intervalos realistas, rote los agentes de usuario y evite el scraping durante las horas de poco tráfico cuando sus solicitudes se destacan.

¿Puedo monitorear las subastas en vivo en tiempo real?

Durante los últimos minutos de una subasta, utilice la automatización del navegador con sesiones previamente autenticadas para minimizar los encuentros con CAPTCHA. La velocidad de CaptchaAI maneja cualquier CAPTCHA que aún aparezca.

Artículos relacionados

  • Cómo resolver reCAPTCHA v2 con callback
  • reCAPTCHA v2 y Turnstile en el mismo sitio
  • Mecanismo de callback de reCAPTCHA v2

Supervisa las subastas de forma fiable: obtén tu API key de CaptchaAI y resuelve los desafíos reCAPTCHA v2 automáticamente.

Los comentarios están deshabilitados para este artículo.