Kullanım Senaryoları

CAPTCHA İşleme ile Tedarik Zinciri İzleme

Tedarik zinciri görünürlüğü yüzlerce tedarikçi portalından, lojistik platformundan ve envanter sisteminden veri gerektirir. Bunların çoğu verilerini CAPTCHA'ların arkasında koruyor. CaptchaAI bu zorlukların üstesinden gelerek işlem hatlarının izlenmesinin kesintisiz çalışmasını sağlar.


CAPTCHA'ların Tedarik Zinciri Verilerini Engellediği Yer

Kaynak Türü CAPTCHA Türü Veri Frekans
Tedarikçi portalları reCAPTCHA v2 Envanter, fiyatlandırma, teslimat süreleri Günlük
Nakliye taşıyıcıları Cloudflare Turnstile Takip, ücretler, teslimat ETA'ları Saatlik
Üretici katalogları Resim CAPTCHA'sı Ürün özellikleri, MOQ'lar Haftalık
Gümrük portalları reCAPTCHA v2 Görev oranları, tarife kodları Günlük
Liman yetkilileri Resim CAPTCHA'sı Gemi programları, liman tıkanıklığı Her 6 saatte bir
Ticaret borsaları reCAPTCHA v3 Spot fiyatlar, vadeli işlemler Gerçek zamanlı

Çoklu Tedarikçi Monitörü

import requests
import time
import re
import json
import base64
from datetime import datetime

CAPTCHAAI_KEY = "YOUR_API_KEY"
CAPTCHAAI_URL = "https://ocr.captchaai.com"


def solve_recaptcha(sitekey, pageurl):
    resp = requests.post(f"{CAPTCHAAI_URL}/in.php", data={
        "key": CAPTCHAAI_KEY, "method": "userrecaptcha",
        "googlekey": sitekey, "pageurl": pageurl, "json": 1,
    })
    task_id = resp.json()["request"]
    for _ in range(60):
        time.sleep(5)
        result = requests.get(f"{CAPTCHAAI_URL}/res.php", params={
            "key": CAPTCHAAI_KEY, "action": "get",
            "id": task_id, "json": 1,
        })
        data = result.json()
        if data["request"] != "CAPCHA_NOT_READY":
            return data["request"]
    raise TimeoutError("Timeout")


def solve_turnstile(sitekey, pageurl):
    resp = requests.post(f"{CAPTCHAAI_URL}/in.php", data={
        "key": CAPTCHAAI_KEY, "method": "turnstile",
        "sitekey": sitekey, "pageurl": pageurl, "json": 1,
    })
    task_id = resp.json()["request"]
    for _ in range(60):
        time.sleep(5)
        result = requests.get(f"{CAPTCHAAI_URL}/res.php", params={
            "key": CAPTCHAAI_KEY, "action": "get",
            "id": task_id, "json": 1,
        })
        data = result.json()
        if data["request"] != "CAPCHA_NOT_READY":
            return data["request"]
    raise TimeoutError("Timeout")


def solve_image(image_bytes):
    img_b64 = base64.b64encode(image_bytes).decode()
    resp = requests.post(f"{CAPTCHAAI_URL}/in.php", data={
        "key": CAPTCHAAI_KEY, "method": "base64",
        "body": img_b64, "json": 1,
    })
    task_id = resp.json()["request"]
    for _ in range(20):
        time.sleep(3)
        result = requests.get(f"{CAPTCHAAI_URL}/res.php", params={
            "key": CAPTCHAAI_KEY, "action": "get",
            "id": task_id, "json": 1,
        })
        data = result.json()
        if data["request"] != "CAPCHA_NOT_READY":
            return data["request"]
    raise TimeoutError("Timeout")


class SupplyChainMonitor:
    def __init__(self, suppliers, proxy=None):
        self.suppliers = suppliers
        self.session = requests.Session()
        if proxy:
            self.session.proxies = {"http": proxy, "https": proxy}
        self.session.headers.update({
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
            "AppleWebKit/537.36 Chrome/126.0.0.0 Safari/537.36",
        })

    def check_all(self):
        """Check inventory and pricing across all suppliers."""
        report = {
            "timestamp": datetime.now().isoformat(),
            "suppliers": {},
        }

        for supplier in self.suppliers:
            try:
                data = self._check_supplier(supplier)
                report["suppliers"][supplier["name"]] = {
                    "status": "success",
                    "data": data,
                }
            except Exception as e:
                report["suppliers"][supplier["name"]] = {
                    "status": "error",
                    "error": str(e),
                }
            time.sleep(3)

        return report

    def _check_supplier(self, supplier):
        url = supplier["url"]
        resp = self.session.get(url, timeout=30)

        # Handle CAPTCHA based on type
        captcha_type = supplier.get("captcha_type")
        if captcha_type and self._has_captcha(resp.text):
            resp = self._solve_captcha(resp, url, supplier)

        from bs4 import BeautifulSoup
        soup = BeautifulSoup(resp.text, "html.parser")

        return {
            "products": self._extract_inventory(soup),
            "last_updated": self._extract_date(soup),
        }

    def _has_captcha(self, html):
        return any(tag in html.lower() for tag in [
            'data-sitekey', 'g-recaptcha', 'cf-turnstile', 'captcha',
        ])

    def _solve_captcha(self, resp, url, supplier):
        captcha_type = supplier.get("captcha_type", "recaptcha")
        sitekey = supplier.get("sitekey", "")

        if not sitekey:
            match = re.search(r'data-sitekey="([^"]+)"', resp.text)
            sitekey = match.group(1) if match else ""

        if captcha_type == "turnstile":
            token = solve_turnstile(sitekey, url)
            return self.session.post(url, data={"cf-turnstile-response": token})
        elif captcha_type == "image":
            match = re.search(r'src="(/captcha[^"]+)"', resp.text)
            if match:
                img_resp = self.session.get(url.rstrip("/") + match.group(1))
                answer = solve_image(img_resp.content)
                return self.session.post(url, data={"captcha": answer})
        else:
            token = solve_recaptcha(sitekey, url)
            return self.session.post(url, data={"g-recaptcha-response": token})

        return resp

    def _extract_inventory(self, soup):
        items = []
        for row in soup.select("table.inventory tr, .product-row"):
            cols = row.select("td, .col")
            if len(cols) >= 3:
                items.append({
                    "sku": cols[0].get_text(strip=True),
                    "stock": cols[1].get_text(strip=True),
                    "price": cols[2].get_text(strip=True),
                })
        return items

    def _extract_date(self, soup):
        date_el = soup.select_one(".last-updated, .update-time")
        return date_el.get_text(strip=True) if date_el else ""


# Configure suppliers
suppliers = [
    {
        "name": "Supplier A",
        "url": "https://supplier-a.example.com/inventory",
        "captcha_type": "recaptcha",
        "sitekey": "6Lc_xxxxxxx",
    },
    {
        "name": "Carrier B",
        "url": "https://carrier-b.example.com/rates",
        "captcha_type": "turnstile",
        "sitekey": "0x4AAAAAAA_xxx",
    },
    {
        "name": "Manufacturer C",
        "url": "https://manufacturer-c.example.com/catalog",
        "captcha_type": "image",
    },
]

monitor = SupplyChainMonitor(
    suppliers=suppliers,
    proxy="http://user:pass@residential.proxy.com:5000",
)
report = monitor.check_all()
print(json.dumps(report, indent=2))

Kargo Oranı Takibi

class ShippingRateTracker:
    def __init__(self, proxy=None):
        self.session = requests.Session()
        if proxy:
            self.session.proxies = {"http": proxy, "https": proxy}
        self.session.headers.update({
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
            "AppleWebKit/537.36 Chrome/126.0.0.0 Safari/537.36",
        })

    def get_rates(self, carrier_url, origin, destination, weight):
        """Fetch shipping rates, handling Turnstile CAPTCHA."""
        resp = self.session.get(carrier_url, timeout=30)

        sitekey_match = re.search(r'data-sitekey="([^"]+)"', resp.text)
        if sitekey_match:
            token = solve_turnstile(sitekey_match.group(1), carrier_url)
            resp = self.session.post(carrier_url, data={
                "origin": origin,
                "destination": destination,
                "weight": weight,
                "cf-turnstile-response": token,
            })

        if resp.status_code == 200:
            return resp.json().get("rates", [])
        return []

Stok Değişikliklerinde Uyarı Verme

def monitor_with_alerts(monitor, alert_thresholds, check_interval=3600):
    """Continuously monitor and alert on inventory changes."""
    previous_data = {}

    while True:
        report = monitor.check_all()

        for supplier, info in report["suppliers"].items():
            if info["status"] != "success":
                continue

            for product in info["data"].get("products", []):
                sku = product["sku"]
                stock = product.get("stock", "")

                # Parse stock level
                try:
                    stock_qty = int(re.sub(r'\D', '', stock))
                except ValueError:
                    continue

                key = f"{supplier}:{sku}"
                prev_qty = previous_data.get(key, stock_qty)

                threshold = alert_thresholds.get(sku, 10)
                if stock_qty < threshold and prev_qty >= threshold:
                    print(f"ALERT: {supplier} - {sku} dropped to {stock_qty}")

                previous_data[key] = stock_qty

        time.sleep(check_interval)

Sağlayıcı geri dönüş politikası

  • Kritik tedarikçileri isteğe bağlı kaynaklardan ayırın, böylece tek bir arıza tüm izleme raporunun boşa gitmesine neden olmaz.
  • Eski verilerin ne zaman kabul edilebilir olduğunu ve eksik bir tedarikçinin ne zaman açık bir olayı tetiklemesi gerektiğini tanımlayın.
  • Tedarikçi üzerindeki ısrarlı CAPTCHA baskısını yalnızca bir mühendislik hatası olarak değil, kaynak bulma riski olarak artırın.

Sorun giderme

Sorun Sebep Düzeltme
Tedarikçi sayfa düzeni değiştirildi Sitenin yeniden tasarımı CSS seçicilerini güncelle
Her çekte CAPTCHA Çok sık kontrol etme Kontroller arasındaki aralığı artırın
Oturumun süresi kontrolün ortasında sona eriyor Portal zaman aşımı Yapışkan oturumu kullanın, daha hızlı kontrol edin
Oran verileri eksik Giriş gerekli Kimlik doğrulama adımı ekle
Yanlış fiyatlar görüntüleniyor Coğrafi tabanlı fiyatlandırma Proxy konumunu pazarla eşleştirin

SSS

Tedarikçi envanterini ne sıklıkla kontrol etmeliyim?

Çoğu tedarikçi için günlük. Tedarik kıtlığı sırasında kritik bileşenler için saatlik. Çok sık yapılan kontroller CAPTCHA'ları daha hızlı tetikler.

Yüzlerce tedarikçiyi izleyebilir miyim?

Evet. Her biri arasında gecikme olacak şekilde tedarikçiler arasında rotasyon yapın. Yükü IP'ler arasında dağıtmak için QA test oturumu'ler kullanın.

Tedarik zinciri sitelerinde en yaygın olan CAPTCHA türü hangisidir?

Tedarikçi portallarında reCAPTCHA v2, lojistik/carrier sitelerinde Cloudflare Turnstile. Eski üretici siteleri genellikle resim CAPTCHA'larını kullanır.


İlgili Kılavuzlar


Tedarik zincirinizi görünür tutun —CaptchaAI anahtarınızı alınve tüm tedarikçi portallarında veri toplamayı otomatikleştirin.

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