← Back to Blog

पार्सर पूल में खराब प्रॉक्सी का चयन: त्रुटि मेट्रिक्स और पायथन पर रोटेशन

हम यह समझते हैं कि कौन सी त्रुटि मेट्रिक्स प्रॉक्सी के डिग्रेडेशन का संकेत देती हैं और कैसे एक स्वचालित आईपी छंटाई और रोटेशन प्रणाली बनाई जाए।

📅October 19, 2026

यदि Wildberries या Ozon का पार्सर अचानक खाली पृष्ठ, टाइमआउट और 403 त्रुटियाँ देने लगा है, तो समस्या हमेशा साइट में नहीं होती। अक्सर प्रॉक्सी पूल में कुछ IP पते पहले ही "सड़ चुके" होते हैं: उन्हें प्रतिबंधित कर दिया गया है, धीमा कर दिया गया है या CAPTCHA के तहत डाल दिया गया है। हम देखते हैं कि किन मेट्रिक्स के आधार पर कार्यात्मक प्रॉक्सी को मृत प्रॉक्सी से अलग किया जाए और बिना मैनुअल नियंत्रण के फ़िल्टरिंग को कैसे स्वचालित किया जाए।

प्रॉक्सी पूल समय के साथ क्यों गिरता है

कोई भी प्रॉक्सी पूल — यहां तक कि विश्वसनीय प्रदाता से खरीदी गई — समय के साथ कार्यात्मक पते का एक हिस्सा खो देता है। कारण भिन्न होते हैं: Wildberries, Ozon और Avito के एंटी-फ्रॉड सिस्टम IP पर प्रतिष्ठा के निशान जमा करते हैं, कुछ पते प्रदाता के अन्य ग्राहकों द्वारा बड़े पैमाने पर अनुरोधों के बाद काले सूचियों में चले जाते हैं (यदि प्रॉक्सी साझा है), डेटा सेंटर रेंज को उप-नेटवर्क के अनुसार बड़े पैमाने पर प्रतिबंधित किया जाता है, और निवासीय IP कभी-कभी बस पूल से बाहर हो जाते हैं क्योंकि वास्तविक उपयोगकर्ता ने उपकरण बंद कर दिया।

यदि पूल को साफ नहीं किया गया, तो "मृत" प्रॉक्सी का हिस्सा गैर-रेखीय रूप से बढ़ता है: पहले 5%, एक सप्ताह के सक्रिय पार्सिंग के बाद — 20-30%। पार्सर कार्यात्मक IP के माध्यम से पुनः प्रयासों पर संसाधनों को खर्च करने लगता है, एक पृष्ठ को इकट्ठा करने का औसत समय बढ़ता है, और लॉग में त्रुटियाँ जमा होती हैं, जो वास्तविक समस्याओं को छिपाती हैं (उदाहरण के लिए, साइट के लेआउट में परिवर्तन)। बिना फ़िल्टरिंग प्रणाली के, आप या तो पूल को "भंडारण" के लिए बढ़ा कर रखते हैं, या नियमित रूप से डेटा संग्रह में विफलता प्राप्त करते हैं।

कार्य केवल त्रुटि के तथ्य को दर्ज करना नहीं है, बल्कि इसे वर्गीकृत करना है: सर्वर की अस्थायी ओवरलोडिंग, विशिष्ट IP का प्रतिबंध, क्षेत्रीय ब्लॉकिंग या पार्सर की ओर से समस्या (गलत हेडर, पुरानी कुकीज़)। त्रुटि के प्रकार पर निर्भर करता है कि क्या प्रॉक्सी को स्थायी रूप से पूल से बाहर फेंकना है, इसे "क्वारंटाइन" में रखना है या बस अनुरोध को फिर से करना है।

फ़िल्टरिंग के लिए प्रमुख त्रुटि मेट्रिक्स

अस्थायी विफलता को वास्तव में मृत प्रॉक्सी से अलग करने के लिए, प्रत्येक IP पर कई मेट्रिक्स एकत्र करना आवश्यक है, न कि एकल HTTP स्थिति पर निर्भर रहना। यहां एक बुनियादी सेट है, जिसे प्रत्येक अनुरोध पर लॉग करना चाहिए:

मेट्रिक यह क्या संकेत करता है क्रिया
HTTP 403 / 429 IP पर प्रतिबंध या दर-सीमा 30-60 मिनट का क्वारंटाइन, पुनरावृत्ति पर — हटाना
संयोग का टाइमआउट प्रॉक्सी ओवरलोडेड या मृत है 3 लगातार टाइमआउट — पूल से हटाना
उत्तर में CAPTCHA IP एंटी-बॉट के संदेह में है अनुरोधों की आवृत्ति कम करें या IP बदलें
उत्तर का समय > 5 सेकंड प्रॉक्सी की ओर से गति में गिरावट पूल में प्राथमिकता कम करना
उत्तर का आकार औसत से कम ब्लॉकिंग पृष्ठ/स्टॉप-गैप दिया गया स्वीकृति से पहले सामग्री की अतिरिक्त जांच
सफल अनुरोधों का हिस्सा (सफलता दर) IP की समग्र गुणवत्ता का मूल्यांकन 50 अनुरोधों में 70% से कम — हटाना

यह महत्वपूर्ण है कि साइट की त्रुटि कोड को नेटवर्क त्रुटियों से न मिलाएं। उदाहरण के लिए, 404 प्रॉक्सी की समस्या नहीं है, बल्कि Wildberries पर अनुपलब्ध उत्पाद है। लेकिन यदि एक ही IP नियमित रूप से 403 प्राप्त करता है जबकि अन्य IP 200 प्राप्त करते हैं — तो यह इस पते के विशेष प्रतिबंध का स्पष्ट संकेत है।

प्रॉक्सी स्कोरिंग एल्गोरिदम

बाइनरी "कार्यात्मक / गैर-कार्यात्मक" के बजाय, प्रत्येक IP के लिए 0 से 100 तक का स्कोर गणना करना अधिक सुविधाजनक है, जो त्रुटियों के साथ धीरे-धीरे कम होता है और सफल अनुरोधों पर पुनर्स्थापित होता है। यह एक случайिक विफलता के बाद प्रॉक्सी को फेंकने की अनुमति नहीं देता (मार्केटप्लेस का सर्वर एक सेकंड के लिए बस लटक सकता है), लेकिन उन IP को जल्दी हटा देता है जो व्यवस्थित रूप से कचरा देते हैं।

लॉजिक सरल है: सफल अनुरोध जो 200 कोड और मान्य सामग्री के साथ होता है, स्कोर में +2 जोड़ता है (लेकिन 100 से अधिक नहीं)। टाइमआउट — -15। कोड 403/429 — -25। उत्तर में CAPTCHA — -20। यदि स्कोर एक थ्रेशोल्ड (उदाहरण के लिए, 30) से नीचे गिरता है, तो प्रॉक्सी एक निश्चित समय के लिए क्वारंटाइन में चला जाता है, और यदि क्वारंटाइन से लौटने के बाद स्कोर फिर से 10 से नीचे गिरता है — IP को स्थायी रूप से पूल से हटा दिया जाता है और विश्लेषण के लिए लॉग किया जाता है।

यह दृष्टिकोण एंटी-डिटेक्ट ब्राउज़रों जैसे Dolphin Anty या AdsPower में प्रतिष्ठा प्रणाली के समान है, जहां खातों की "स्वास्थ्य" गतिविधि के आधार पर होती है। यही तंत्र IP पतों के लिए पार्सिंग में भी अच्छी तरह से काम करता है।

कोड: Python में स्वचालित फ़िल्टरिंग के साथ ProxyPool

नीचे — त्रुटि मेट्रिक्स को ध्यान में रखते हुए प्रॉक्सी पूल प्रबंधित करने के लिए कक्षा का कार्यात्मक ढांचा है। इसे किसी भी पार्सर पर requests, httpx या Scrapy के साथ जोड़ा जा सकता है, प्रॉक्सी प्राप्त करने की लॉजिक को pool.get_proxy() के कॉल से बदलकर।

import time
import random
from dataclasses import dataclass, field
from typing import Optional

@dataclass
class ProxyStats:
    address: str
    score: int = 100
    quarantine_until: float = 0.0
    total_requests: int = 0
    total_success: int = 0
    consecutive_timeouts: int = 0
    is_dead: bool = False

    @property
    def success_rate(self) -> float:
        if self.total_requests == 0:
            return 1.0
        return self.total_success / self.total_requests


class ProxyPool:
    def __init__(self, proxies: list[str],
                 min_score: int = 30,
                 dead_score: int = 10,
                 quarantine_seconds: int = 1800):
        self.stats = {p: ProxyStats(address=p) for p in proxies}
        self.min_score = min_score
        self.dead_score = dead_score
        self.quarantine_seconds = quarantine_seconds

    def _is_available(self, stats: ProxyStats) -> bool:
        if stats.is_dead:
            return False
        if stats.quarantine_until > time.time():
            return False
        return True

    def get_proxy(self) -> Optional[str]:
        available = [s for s in self.stats.values() if self._is_available(s)]
        if not available:
            return None
        # स्कोर के अनुसार क्रमबद्ध करें, शीर्ष 30% में से एक यादृच्छिक लें, ताकि एक IP को न मारें
        available.sort(key=lambda s: s.score, reverse=True)
        top_pool = available[:max(1, len(available) // 3)]
        return random.choice(top_pool).address

    def report_success(self, proxy: str):
        s = self.stats[proxy]
        s.total_requests += 1
        s.total_success += 1
        s.consecutive_timeouts = 0
        s.score = min(100, s.score + 2)

    def report_timeout(self, proxy: str):
        s = self.stats[proxy]
        s.total_requests += 1
        s.consecutive_timeouts += 1
        s.score -= 15
        if s.consecutive_timeouts >= 3:
            self._quarantine(s)
        self._check_dead(s)

    def report_blocked(self, proxy: str, captcha: bool = False):
        s = self.stats[proxy]
        s.total_requests += 1
        s.score -= 20 if captcha else 25
        self._quarantine(s)
        self._check_dead(s)

    def _quarantine(self, s: ProxyStats):
        if s.score < self.min_score:
            s.quarantine_until = time.time() + self.quarantine_seconds

    def _check_dead(self, s: ProxyStats):
        if s.score <= self.dead_score:
            s.is_dead = True

    def stats_report(self) -> list[dict]:
        return [
            {
                "proxy": s.address,
                "score": s.score,
                "success_rate": round(s.success_rate, 2),
                "dead": s.is_dead,
            }
            for s in self.stats.values()
        ]

वास्तविक पार्सर में report_success, report_timeout और report_blocked को प्रत्येक HTTP अनुरोध के बाद प्रतिक्रिया हैंडलर में सीधे डाला जाता है। अनुरोधों के साथ एकीकरण का उदाहरण:

import requests

def fetch(url: str, pool: ProxyPool):
    proxy = pool.get_proxy()
    if not proxy:
        raise RuntimeError("पूल में कोई उपलब्ध प्रॉक्सी नहीं है")

    proxies = {"http": proxy, "https": proxy}
    try:
        resp = requests.get(url, proxies=proxies, timeout=8)
    except requests.exceptions.Timeout:
        pool.report_timeout(proxy)
        return None

    if resp.status_code in (403, 429):
        pool.report_blocked(proxy)
        return None

    if "captcha" in resp.text.lower():
        pool.report_blocked(proxy, captcha=True)
        return None

    pool.report_success(proxy)
    return resp

यह दृष्टिकोण मैनुअल निगरानी के बोझ को कम करता है: आप एक बार थ्रेशोल्ड सेट करते हैं, और फिर पूल खुद "ठीक हो जाता है", मृत पतों को बाहर निकालता है और क्वारंटाइन से उन पतों को वापस लाता है जो अस्थायी रूप से लटके हुए थे।

IP के लिए थ्रेशोल्ड मान

सार्वभौमिक संख्याएँ नहीं होतीं — थ्रेशोल्ड साइट और उसके एंटी-बॉट की आक्रामकता पर निर्भर करते हैं। लेकिन कुछ संकेतक हैं, जो Wildberries, Ozon और Avito पर पार्सिंग के दौरान अच्छी तरह से काम करते हैं:

  • 70% से कम सफलता दर 30-50 अनुरोधों के नमूने पर — IP को हटाने का कारण, भले ही वर्तमान स्कोर अभी तक गंभीर न हो।
  • लगातार 3 टाइमआउट — लगभग हमेशा यह संकेत करता है कि प्रॉक्सी भौतिक रूप से अनुपलब्ध है या ओवरलोडेड है, इसे सक्रिय पूल में रखना बेकार है।
  • 20 अनुरोधों में 1 बार से अधिक CAPTCHA — IP पहले से ही एंटी-बॉट के संदेह में है, बेहतर है कि अनुरोधों की आवृत्ति कम करें या पता बदलें।
  • उत्तर का औसत समय पूल के मध्य से 2x अधिक — गिरावट का संकेत, गंभीर नहीं है, लेकिन चयन के समय प्राथमिकता कम करने का कारण है।

30-60 मिनट का क्वारंटाइन आमतौर पर डेटा सेंटर और निवासीय प्रॉक्सियों के लिए पर्याप्त होता है, ताकि एंटी-बॉट "अस्थायी संदेहास्पद गतिविधि" को "भूल" जाए। मोबाइल प्रॉक्सी के लिए स्थिति अलग है: वहां IP ऑपरेटर द्वारा सेल बदलने पर बदलता है, इसलिए क्वारंटाइन को छोटा किया जा सकता है — 10-15 मिनट, क्योंकि रोटेशन के बाद यह भौतिक रूप से एक अलग पता होता है।

हेल्थचेक और बैकग्राउंड में रोटेशन

प्रतिक्रियाशील फ़िल्टरिंग (पार्सिंग के मुख्य प्रवाह में त्रुटियों के आधार पर) के अलावा, बैकग्राउंड हेल्थचेक चलाना उपयोगी है — एक अलग प्रक्रिया, जो हर कुछ मिनटों में प्रॉक्सी को हल्के अनुरोधों के साथ एक तटस्थ URL (उदाहरण के लिए, httpbin.org/ip) पर पिंग करती है और पूल की सांख्यिकी को अपडेट करती है इससे पहले कि प्रॉक्सी Wildberries या Ozon के लिए वास्तविक अनुरोध में जाए।

import threading

def healthcheck_loop(pool: ProxyPool, interval: int = 300):
    while True:
        for proxy in list(pool.stats.keys()):
            try:
                r = requests.get(
                    "https://httpbin.org/ip",
                    proxies={"http": proxy, "https": proxy},
                    timeout=5
                )
                if r.status_code == 200:
                    pool.report_success(proxy)
                else:
                    pool.report_blocked(proxy)
            except requests.exceptions.RequestException:
                pool.report_timeout(proxy)
        time.sleep(interval)

threading.Thread(target=healthcheck_loop, args=(pool,), daemon=True).start()

ऐसा बैकग्राउंड प्रोसेस विशेष रूप से महत्वपूर्ण है, यदि पूल बड़ा है (सैकड़ों IP) और पार्सिंग निरंतर नहीं होती, बल्कि पैक में होती है — बिना हेल्थचेक के, कुछ प्रॉक्सी बस "सड़ने" के लिए पर्याप्त समय पाती हैं, और पार्सिंग के पहले मिनटों को जीवित फ़िल्टरिंग में खर्च किया जाता है, बजाय इसके कि तुरंत सत्यापित पतों के साथ काम किया जाए।

मार्केटप्लेस के लिए कौन सा प्रॉक्सी प्रकार चुनें

प्रॉक्सी के प्रकार का चयन सीधे इस पर निर्भर करता है कि आपको फ़िल्टरिंग कितनी बार करनी होगी और थ्रेशोल्ड कितने आक्रामक होंगे। Wildberries और Ozon के स्थिर पार्सिंग के लिए, जहां एंटी-बॉट व्यवहार पैटर्न और उप-नेटवर्क की प्रतिष्ठा का विश्लेषण करता है, निवासीय प्रॉक्सी सबसे अच्छा प्रदर्शन करते हैं — उनके IP वास्तविक घरेलू इंटरनेट प्रदाताओं के हैं, और एंटी-बॉट उन्हें उप-नेटवर्क के अनुसार समूह में प्रतिबंधित करने की संभावना कम होती है।

अधिक सरल और कम सुरक्षित स्रोतों (उदाहरण के लिए, Avito से सार्वजनिक डेटा एकत्र करना या सरल विंडो पर कीमतों की निगरानी करना) के लिए अक्सर डेटा सेंटर प्रॉक्सी पर्याप्त होती हैं — वे तेज और सस्ती होती हैं, जो बड़े पैमाने पर अनुरोधों के लिए महत्वपूर्ण है, लेकिन वे थोड़ी अधिक बार प्रतिबंधित होती हैं, इसलिए उनके लिए फ़िल्टरिंग के थ्रेशोल्ड को सख्त बनाना चाहिए।

प्रॉक्सी का प्रकार फ़िल्टरिंग की गति कब उपयोग करें
डेटा सेंटर उच्च, उप-नेटवर्क समूह में प्रतिबंधित होते हैं सरल विंडो, बड़े पैमाने पर, कम सुरक्षा
निवासीय मध्यम, IP विशेष रूप से प्रतिबंधित होते हैं Wildberries, Ozon, एंटी-बॉट वाली साइटें
मोबाइल कम, IP स्वचालित रूप से ऑपरेटर द्वारा बदलता है कठोर सुरक्षा वाले स्रोत, उच्च आवृत्ति पार्सिंग

व्यवहार में, कई टीमें हाइब्रिड पूल का उपयोग करती हैं: अधिकांश अनुरोध निवासीय IP के माध्यम से होते हैं, और जब बड़े पैमाने पर प्रतिबंध होते हैं, तो मोबाइल प्रॉक्सी को "आपातकालीन" रिजर्व के रूप में जोड़ा जाता है, क्योंकि उनका IP स्वचालित रूप से सेल नेटवर्क के रोटेशन के माध्यम से बदलता है और मैनुअल हस्तक्षेप की आवश्यकता नहीं होती है।

निष्कर्ष

बिना फ़िल्टरिंग प्रणाली के प्रॉक्सी पूल अनिवार्य रूप से गिरता है, और जितना अधिक समय यह बिना सफाई के काम करता है, उतना ही अधिक संसाधन पार्सर बेकार में मृत IP पर खर्च करता है। HTTP कोड, टाइमआउट, CAPTCHA और सफलता दर को ध्यान में रखते हुए स्कोरिंग मॉडल स्वचालित रूप से समस्याग्रस्त पतों की पहचान करने और बिना मैनुअल नियंत्रण के पूल को कार्यात्मक बनाए रखने की अनुमति देता है। इस लेख का कोड किसी भी स्टैक के लिए अनुकूलित किया जा सकता है — requests, httpx, Scrapy या अपना स्वयं का असिंक्रोनस पार्सर।

यदि आप केवल मार्केटप्लेस के लिए पार्सिंग के लिए पूल इकट्ठा कर रहे हैं और प्रारंभ में प्रतिबंधों की आवृत्ति को कम करना चाहते हैं, तो हम निवासीय प्रॉक्सी पर ध्यान देने की सिफारिश करते हैं — वे सामान्य डेटा सेंटर पतों की तुलना में Wildberries और Ozon जैसी सुरक्षित साइटों पर स्पष्ट रूप से उच्च सफलता दर प्रदान करते हैं।