Anwendungsfälle

CAPTCHA-Verwaltung für die Überwachung der Auktionsseite

Auktionsplattformen schützen Listungsdaten und Suchfunktionen mit reCAPTCHA v2. CAPTCHAs erscheinen am häufigsten bei schnellen Suchanfragen, Detailansichten von Einträgen und der Suche nach Angebotshistorien. So gewährleisten Sie eine zuverlässige Überwachung aller Auktionsseiten.

Wo CAPTCHAs auf Auktionsseiten ausgelöst werden

Aktion CAPTCHA-Typ Triggermuster
Suche /browse-Einträge reCAPTCHA v2 Schnelle sequentielle Suche
Eintragsdetails anzeigen reCAPTCHA v2 Hohes Volumen von derselben IP
Überprüfen Sie den Gebotsverlauf reCAPTCHA v2 Wiederholtes Laden der Detailseite
Durchsuchen von Kategorien Cloudflare Turnstile Bot-ähnliche Navigationsgeschwindigkeit
Preisalarmseiten reCAPTCHA v2 Häufige Aktualisierungen

Auktionsüberwachung mit CAPTCHA-Lösung

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

Preisalarmsystem (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();

Überwachungsstrategie

Frequenz prüfen Anwendungsfall Erwartete CAPTCHA-Rate
Alle 30 Sekunden Last-Minute-Gebot Hoch – Proxys verwenden
Alle 5 Minuten Aktive Auktionsverfolgung Mäßig
Alle 15 Minuten Beobachtungslistenüberwachung Niedrig
Jede Stunde Langfristige Preisforschung Minimal

Reduzierung der CAPTCHA-Häufigkeit

Technik Auswirkungen
Sitzungscookies wiederverwenden Behält den authentifizierten Status bei
Residential-Proxys rotieren Verteilt Anfragen über IPs
Anforderungsintervalle randomisieren Vermeidet periodische Erkennungsmuster
Verwenden Sie authentifizierte Konten Niedrigere CAPTCHA-Auslöseschwellen

Fehlerbehebung

Problem Ursache Lösung
Zu viele CAPTCHAs in kurzer Zeit Abrufrate oder Parallelität ist für die Quelle zu aggressiv Drossele Intervalle, halte Sessions stabil und prüfe die Qualität deiner Proxys
Daten fehlen trotz gelöster CAPTCHA Der Parser liest eine alte oder unvollständige Ansicht aus Extrahiere Daten erst nach erfolgreicher Token-Anwendung in derselben Sitzung
Kosten steigen stärker als erwartet Zu viele Wiederholungen oder unnötige Seitenaufrufe lösen zusätzliche Challenges aus Löse nur kritische Schritte und protokolliere Wiederholungen pro Quelle

Verwandte Leitfäden

Diskussionen (0)

Noch keine Kommentare.