Kasus Penggunaan

Penanganan CAPTCHA untuk Pemantauan Situs Lelang

Platform lelang melindungi data daftar dan fungsi pencarian dengan reCAPTCHA v2. CAPTCHA paling sering muncul selama kueri penelusuran cepat, tampilan detail daftar, dan pencarian riwayat tawaran. Berikut cara mempertahankan pemantauan yang andal di seluruh situs lelang.

Dimana CAPTCHA Dipicu di Situs Lelang

Tindakan Jenis CAPTCHA Pola pemicu
Cari daftar /browse reCAPTCHA v2 Pencarian berurutan yang cepat
Lihat detail daftar reCAPTCHA v2 Volume tinggi dari IP yang sama
Periksa riwayat tawaran reCAPTCHA v2 Halaman detail berulang dimuat
Penjelajahan kategori Cloudflare Turnstile Kecepatan navigasi seperti bot
Halaman peringatan harga reCAPTCHA v2 Penyegaran yang sering

Pemantauan Lelang dengan Pemecahan 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"
)

Sistem Peringatan Harga (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();

Strategi Pemantauan

Periksa frekuensi Kasus penggunaan Tarif CAPTCHA yang diharapkan
Setiap 30 detik Penawaran menit terakhir Tinggi – gunakan proxy
Setiap 5 menit Pelacakan lelang aktif Sedang
Setiap 15 menit Pemantauan daftar pantauan Rendah
Setiap jam Riset harga jangka panjang Minimal

Mengurangi Frekuensi CAPTCHA

Teknik Dampak
Gunakan kembali cookie sesi Mempertahankan status terotentikasi
Putar proxy perumahan Mendistribusikan permintaan ke seluruh IP
Acak interval permintaan Menghindari pola deteksi berkala
Gunakan akun yang diautentikasi Turunkan ambang batas pemicu CAPTCHA

Pemecahan Masalah

Masalah Penyebab Solusi
CAPTCHA pada setiap permintaan Tidak ada persistensi sesi Gunakan kembali requests.Session()
Token reCAPTCHA ditolak Token kedaluwarsa (umur 2 menit) Selesaikan sesaat sebelum diserahkan
Halaman daftar menunjukkan 0 hasil CAPTCHA memfilter hasil secara diam-diam Periksa elemen CAPTCHA yang tersembunyi
IP diblokir setelah banyak CAPTCHA Batas laju terlampaui Putar proxy, tingkatkan interval

Pertanyaan Umum

Seberapa cepat saya bisa memeriksa daftar lelang?

CaptchaAI menyelesaikan reCAPTCHA v2 dalam 10–30 detik. Untuk lelang yang sensitif terhadap waktu, selesaikan token terlebih dahulu dan putar proxy untuk meminimalkan penundaan.

Akankah situs lelang mendeteksi pemantauan?

Deteksi bergantung pada pola permintaan, bukan penyelesaian CAPTCHA. Gunakan interval yang realistis, rotasikan agen pengguna, dan hindari melakukan scraping selama jam-jam lalu lintas rendah ketika permintaan Anda menonjol.

Bisakah saya memantau lelang langsung secara real-time?

Pada menit-menit terakhir lelang, gunakan otomatisasi browser dengan sesi yang telah diautentikasi sebelumnya untuk meminimalkan pertemuan CAPTCHA. Kecepatan CaptchaAI menangani CAPTCHA apa pun yang masih muncul.

Artikel Terkait

  • Cara Mengatasi Callback Recaptcha V2 Menggunakan Api
  • Penanganan reCAPTCHA v2 dan Turnstile di Situs yang Sama
  • Mekanisme Callback reCAPTCHA v2

Langkah Selanjutnya

Pantau lelang dengan andal – dapatkan kunci API CaptchaAI Anda dan selesaikan tantangan reCAPTCHA v2 secara otomatis.

Komentar dinonaktifkan untuk artikel ini.