Use Cases

Açık Artırma Sitesi İzleme için CAPTCHA Kullanımı

Açık artırma listelerinde teklifleri ve fiyat hareketlerini otomatik izlerken karşınıza çıkan asıl engel reCAPTCHA v2'dir: arama, ilan ayrıntısı ve teklif geçmişi sayfaları belirli bir istek hızının üzerine çıktığınızda doğrulama ister. Çözüm nettir — doğrulamayı CaptchaAI API'si ile çözer, aynı oturumda isteğe devam eder ve izleme akışınızı kesintiye uğratmazsınız. Aşağıda, koleksiyon ürünlerinden ikinci el elektroniğe kadar tipik bir fiyat takibi senaryosunu reCAPTCHA v2 çözümüyle uçtan uca kuran Python ve JavaScript örneklerini bulacaksınız.

Açık artırma sitelerinde CAPTCHA nerede tetiklenir?

Açık artırma platformları, listeleme verisini ve arama işlevini reCAPTCHA v2 ile korur. Doğrulama en sık şu noktalarda devreye girer:

Eylem CAPTCHA türü Tetikleyici desen
Arama ve listeleme gezintisi reCAPTCHA v2 Hızlı, ardışık aramalar
İlan ayrıntısını görüntüleme reCAPTCHA v2 Aynı IP'den yüksek hacim
Teklif geçmişini sorgulama reCAPTCHA v2 Tekrarlı ayrıntı sayfası yüklemeleri
Kategori gezinme Cloudflare Turnstile Bot benzeri gezinme hızı
Fiyat uyarısı sayfaları reCAPTCHA v2 Sık sayfa yenilemeleri

reCAPTCHA v2 çözümüyle açık artırma izleme (Python)

Aşağıdaki AuctionMonitor sınıfı arama ve ilan isteklerini gönderir; bir CAPTCHA gördüğünde sitekey'i çıkarır, CaptchaAI ile çözer ve token'ı g-recaptcha-response alanıyla yeniden gönderir. requests.Session() sayesinde oturum kalıcılığı korunur, böylece her istekte yeniden doğrulama gerekmez.

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

Fiyat takibi ve uyarı sistemi (JavaScript)

İzleme listenizdeki ilanların fiyatı belirlediğiniz eşiğe yaklaştığında uyarı üretmek isterseniz, aynı çözüm akışını JavaScript tarafında kurabilirsiniz. AuctionTracker her ilanı sorgular, gerektiğinde reCAPTCHA v2'yi çözer ve fiyat sınıra ulaştığında bir uyarı listesi döndürür.

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

İzleme sıklığını nasıl seçersiniz

Kontrol sıklığı arttıkça beklenen CAPTCHA oranı da yükselir. İhtiyacınıza göre bir denge kurun:

Kontrol sıklığı Kullanım örneği Beklenen CAPTCHA oranı
Her 30 saniyede bir Son dakika teklifleri Yüksek — proxy ile istekleri dağıtın
Her 5 dakikada bir Aktif açık artırma takibi Orta
Her 15 dakikada bir İzleme listesi takibi Düşük
Saatte bir Uzun vadeli fiyat araştırması En düşük

CAPTCHA sıklığını azaltma teknikleri

Aynı hacimde veriyi daha az doğrulamayla toplamak için istek desenlerinizi düzenleyin:

  • Oturum çerezini yeniden kullanın — kimlik doğrulama durumunu korur ve her istekte yeniden doğrulama gerekmez.
  • Proxy ile istekleri farklı IP'lere yayın — tek bir IP'den gelen yoğunluğu azaltır.
  • İstek aralıklarını sabit tutmayın — öngörülebilir, periyodik trafik desenini zayıflatır.
  • Kimliği doğrulanmış hesap kullanın — CAPTCHA tetikleme eşiğini düşürür.

Sorun giderme

Sorun Sebep Düzeltme
Her istekte CAPTCHA çıkıyor Oturum kalıcılığı yok requests.Session()'ı yeniden kullanın
reCAPTCHA v2 token'ı reddedildi Token'ın ömrü doldu (2 dakika) Göndermeden hemen önce çözün
Listeleme sayfası 0 sonuç gösteriyor CAPTCHA sonuçları sessizce filtreledi Gizli CAPTCHA öğelerini kontrol edin
Çok sayıda CAPTCHA sonrası IP engellendi İstek sınırı aşıldı İstek aralıklarını artırın, proxy ile yükü dağıtın

Maliyet ve doğru planı seçme

Açık artırma izleme genellikle sürekli çalışan bir iş akışıdır; maliyeti belirleyen şey çözdüğünüz CAPTCHA sayısı değil, kaç eşzamanlı thread'e ihtiyaç duyduğunuzdur. CaptchaAI thread başına ücretlendirir ve her planda thread başına sınırsız çözüm sunar; bu, TL'nin dalgalı seyrettiği bir ortamda öngörülebilir aylık USD maliyeti demektir.

Tek bir izleme listesini düşük sıklıkla takip eden bir otomasyon geliştiricisi için BASIC ($15/ay, 5 thread) çoğu zaman yeterlidir. Birden fazla açık artırmayı paralel izleyen, son dakika tekliflerini yakından takip eden bir iş akışında STANDARD ($30/ay, 15 thread) daha rahat bir eşzamanlılık sağlar. Fiyatlar USD üzerinden sabittir; güncel değerler için CaptchaAI fiyatlandırma sayfasına bakın.

Not: Açık artırma listelerinden topladığınız veriler kişisel veri içeriyorsa, Türkiye'de KVKK kapsamına girebilir. İzleme iş akışlarınızı yetkili olduğunuz veri ve hesaplarla sınırlı tutun.

Sık sorulan sorular

Açık artırma sitelerinde hangi CAPTCHA türleriyle karşılaşırım?

Çoğunlukla reCAPTCHA v2; bazı kategori ve gezinme sayfalarında Cloudflare Turnstile çıkabilir. CaptchaAI her ikisini de çözer, dolayısıyla tek bir entegrasyonla iki türü de yönetebilirsiniz.

reCAPTCHA v2 token'ı neden reddedildi?

En yaygın sebep süredir: token'ın kullanım ömrü yaklaşık 2 dakikadır. Token'ı isteği göndermeden hemen önce çözün ve çözüm sırasındaki pageurl ile isteğin adresi aynı olsun.

İzleme için hangi CaptchaAI planı yeterli?

Tek bir izleme listesini seyrek kontrol ediyorsanız BASIC ($15/ay, 5 thread) yeterlidir. Birden fazla açık artırmayı paralel ve sık izliyorsanız STANDARD ($30/ay, 15 thread) daha fazla eşzamanlı thread verir. Fiyatlar USD'dir.

Açık artırmanın son dakikalarında CAPTCHA'ları nasıl yönetirim?

Son dakikalarda önceden kimliği doğrulanmış bir oturumla tarayıcı otomasyonu kullanın; bu, karşılaşılan CAPTCHA sayısını azaltır. Yine de çıkan reCAPTCHA v2 doğrulamalarını CaptchaAI genellikle 60 saniyenin altında çözer.

İlgili Makaleler

Sonraki Adımlar

Açık artırmaları kesintisiz izlemeye bugün başlayın — CaptchaAI API anahtarınızı alın ve karşınıza çıkan reCAPTCHA v2 doğrulamalarını otomatik olarak çözün.

Bu makale için yorumlar devre dışı bırakılmıştır.