Back to Blog

मेडिकल डेटा पार्सिंग के लिए प्रॉक्सी: बिना ब्लॉक के जानकारी कैसे इकट्ठा करें

जानें कि कैसे क्लिनिकल रिसर्च, दवा डेटाबेस और मेडिकल जर्नल से मेडिकल डेटा को सुरक्षित रूप से पार्स करें, बिना ब्लॉक हुए।

📅March 9, 2026
```html

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

चिकित्सा साइटें पार्सिंग को क्यों ब्लॉक करती हैं

चिकित्सा पोर्टल और डेटाबेस स्वचालित जानकारी संग्रह के प्रति विशेष रूप से संवेदनशील होते हैं, इसके कई कारण हैं। सबसे पहले, इनमें से कई वाणिज्यिक आधार पर काम करते हैं और डेटा के लिए भुगतान की सदस्यता के माध्यम से पहुंच बेचते हैं। स्वचालित पार्सिंग उपयोग की शर्तों और लाइसेंस समझौतों का उल्लंघन कर सकती है।

दूसरे, चिकित्सा डेटा अक्सर संवेदनशील जानकारी होती है, जो कानून द्वारा सुरक्षित होती है (अमेरिका में HIPAA, यूरोप में GDPR)। संसाधनों के मालिकों को ऐसे डेटा तक पहुंच को नियंत्रित करने और उनके अनधिकृत वितरण को रोकने की आवश्यकता होती है। इसलिए वे उन्नत सुरक्षा प्रणालियों का उपयोग करते हैं:

  • दर सीमित करना — प्रति समय एक IP पते से अनुरोधों की संख्या को सीमित करना (आमतौर पर प्रति मिनट 10-50 अनुरोध)
  • फिंगरप्रिंटिंग — ब्राउज़र के लक्षणों, HTTP हेडर, संसाधनों के लोडिंग क्रम का विश्लेषण
  • CAPTCHA — संदिग्ध गतिविधि पर प्रतिक्रिया करने वाली reCAPTCHA v3 जैसी प्रणालियाँ
  • IP ब्लॉकिंग — डेटा केंद्रों के IP पते का अस्थायी या स्थायी ब्लॉक
  • Cloudflare और समान — CDN स्तर पर बॉट्स के खिलाफ सुरक्षा

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

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

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

प्रॉक्सी के प्रकार का चयन चिकित्सा डेटा के सफल पार्सिंग के लिए महत्वपूर्ण है। विभिन्न स्रोतों के लिए विभिन्न दृष्टिकोण की आवश्यकता होती है। आइए प्रॉक्सी के मुख्य प्रकारों और उनकी उपयुक्तता पर विचार करें:

प्रॉक्सी का प्रकार लाभ नुकसान कब उपयोग करें
डेटा सेंटर प्रॉक्सी उच्च गति (100+ एमबीपीएस), कम लागत, स्थिर कनेक्शन आसान पहचान, अक्सर सुरक्षित साइटों पर ब्लॉक होते हैं खुले डेटाबेस बिना कड़े सुरक्षा (PubMed, WHO)
रिज़िडेंट प्रॉक्सी वास्तविक घरेलू उपयोगकर्ताओं के IP, ब्लॉक होने का कम जोखिम, Cloudflare को पार करते हैं उच्च लागत, परिवर्तनशील गति, अस्थिर हो सकते हैं सुरक्षित वाणिज्यिक डेटाबेस (Elsevier, Springer), Cloudflare के साथ साइटें
मोबाइल प्रॉक्सी अधिकतम विश्वास (मोबाइल ऑपरेटरों के IP), लगभग ब्लॉक नहीं होते सबसे महंगे, सीमित भूगोल, धीमे हो सकते हैं विशेष रूप से सुरक्षित संसाधन, जब रिज़िडेंट प्रॉक्सी मदद नहीं करते
ISP प्रॉक्सी डेटा सेंटर की गति + रिज़िडेंट का विश्वास, स्थिर IP औसत लागत, सीमित उपलब्धता एक IP से दीर्घकालिक पार्सिंग, जब स्थिरता की आवश्यकता हो

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

विशिष्ट स्रोतों के लिए चयन के लिए सिफारिशें

  • PubMed, PubMed Central — डेटा सेंटर प्रॉक्सी पर्याप्त हैं, लेकिन प्रति सेकंड 3 अनुरोधों की सीमा के साथ
  • ClinicalTrials.gov — डेटा सेंटर प्रॉक्सी, आधिकारिक API है
  • Elsevier, Springer, Wiley — रिज़िडेंट प्रॉक्सी अनिवार्य हैं, उन्नत फिंगरप्रिंटिंग का उपयोग करते हैं
  • DrugBank, RxList — रिज़िडेंट प्रॉक्सी, पार्सिंग के खिलाफ सक्रिय सुरक्षा
  • FDA, EMA डेटाबेस — डेटा सेंटर प्रॉक्सी उपयुक्त हैं, लेकिन धीमी पार्सिंग गति के साथ

चिकित्सा डेटा के मुख्य स्रोत और उनकी सुरक्षा

चिकित्सा डेटा कई स्रोतों में वितरित होते हैं, प्रत्येक की अपनी विशिष्टता और सुरक्षा स्तर होता है। इन विशेषताओं को समझना पार्सिंग रणनीति को सही तरीके से सेट करने में मदद करेगा।

खुले सरकारी डेटाबेस

PubMed/PubMed Central — चिकित्सा प्रकाशनों का सबसे बड़ा डेटाबेस, जिसमें 35 मिलियन से अधिक रिकॉर्ड हैं। अमेरिका की राष्ट्रीय चिकित्सा पुस्तकालय (NLM) आधिकारिक API E-utilities प्रदान करती है, जो डेटा तक पहुंच का प्राथमिक तरीका है। वेब इंटरफेस का सीधा पार्सिंग संभव है, लेकिन एक IP से प्रति सेकंड 3 अनुरोधों तक सीमित है। सीमा से अधिक होने पर 24 घंटे के लिए अस्थायी ब्लॉक हो जाता है।

ClinicalTrials.gov — क्लिनिकल परीक्षणों का डेटाबेस, जिसमें 220 देशों में 400,000 से अधिक परीक्षणों की जानकारी है। यह प्रोग्रामेटिक पहुंच के लिए API भी प्रदान करता है। वेब इंटरफेस दर सीमित करने से सुरक्षित है — प्रति IP 5 मिनट में अधिकतम 100 अनुरोध। बॉट्स के खिलाफ बुनियादी सुरक्षा का उपयोग किया जाता है, लेकिन Cloudflare के बिना।

FDA दवाओं का डेटाबेस — FDA द्वारा अनुमोदित दवाओं का डेटाबेस। वेब इंटरफेस और API openFDA के माध्यम से खुली पहुंच। सीमाएँ: अनाम उपयोगकर्ताओं के लिए प्रति मिनट 240 अनुरोध, API कुंजी के साथ प्रति मिनट 1000 अनुरोध। ब्लॉकिंग दुर्लभ है, लेकिन आक्रामक पार्सिंग के दौरान संभव है।

वाणिज्यिक वैज्ञानिक प्रकाशक

Elsevier (ScienceDirect) — वैज्ञानिक साहित्य के सबसे बड़े प्रकाशकों में से एक। यह बहु-स्तरीय सुरक्षा का उपयोग करता है: Cloudflare, ब्राउज़र का फिंगरप्रिंटिंग, उपयोगकर्ता के व्यवहार का विश्लेषण। यह स्वचालित डाउनलोडिंग के पैटर्न का पता लगाता है: लेखों तक अनुक्रमिक पहुंच, JavaScript की अनुपस्थिति, असामान्य User-Agent। पार्सिंग का पता चलने पर यह खाते के स्तर पर IP को ब्लॉक कर देता है और पूरे संस्थान को ब्लॉक कर सकता है। रोटेशन और ब्राउज़र की पूरी अनुकरण के साथ रिज़िडेंट प्रॉक्सी का उपयोग अनिवार्य है।

Springer Nature — समान सुरक्षा, इसके अलावा पृष्ठों के स्क्रॉलिंग की गति और माउस की गति की निगरानी करता है। बॉट्स का पता लगाने के लिए मशीन लर्निंग का उपयोग करता है। सिफारिश की जाती है कि प्रति IP प्रति घंटे 10-15 लेखों से अधिक न पार्स करें, अनुरोधों के बीच यादृच्छिक देरी के साथ।

Wiley Online Library — कम आक्रामक सुरक्षा, लेकिन फिर भी प्रॉक्सी के उपयोग की आवश्यकता है। यह प्रति IP बिना ब्लॉक के प्रति घंटे लगभग 50 अनुरोधों की अनुमति देता है। गतिविधि की निगरानी के लिए सत्र कुकीज़ का उपयोग करता है।

फार्मास्यूटिकल डेटाबेस

DrugBank — दवाओं का एक व्यापक डेटाबेस। मुफ्त संस्करण वेब इंटरफेस तक सीमित है, वाणिज्यिक संस्करण API और डेटा निर्यात प्रदान करता है। वेब संस्करण Cloudflare और दर सीमित करने से सुरक्षित है — प्रति मिनट अधिकतम 20 अनुरोध। कुकीज़ और JavaScript की अनुपस्थिति के लिए स्वचालन का पता लगाता है।

RxList, Drugs.com — उपभोक्ताओं के लिए लोकप्रिय दवाओं के संदर्भ। ये Cloudflare का उपयोग करते हैं और पार्सिंग के खिलाफ सक्रिय रूप से लड़ते हैं। डेटा केंद्रों के IP को लगभग तुरंत ब्लॉक करते हैं। रिज़िडेंट प्रॉक्सी और धीमी पार्सिंग गति (5-10 पृष्ठ प्रति मिनट) की आवश्यकता होती है।

दीर्घकालिक पार्सिंग के लिए IP रोटेशन सेट करना

IP पते की सही रोटेशन चिकित्सा डेटा के सफल पार्सिंग के लिए एक कुंजी कारक है। दो मुख्य दृष्टिकोण हैं: अनुरोधों के स्तर पर रोटेशन और समय के अनुसार रोटेशन।

अनुरोधों के स्तर पर रोटेशन

इस दृष्टिकोण में, प्रत्येक अनुरोध एक नए IP पते के माध्यम से भेजा जाता है। यह ब्लॉक होने के जोखिम को अधिकतम रूप से कम करता है, लेकिन उन साइटों के साथ समस्याएँ उत्पन्न कर सकता है जो कुकीज़ के माध्यम से सत्रों को ट्रैक करती हैं। यह सूचियों और निर्देशिकाओं के पार्सिंग के लिए उपयुक्त है, जहां सत्र की स्थिति बनाए रखने की आवश्यकता नहीं होती है।

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

समय के अनुसार रोटेशन (स्टिकी सत्र)

स्टिकी सत्र एक निश्चित समय (आमतौर पर 5-30 मिनट) के लिए एक IP पते का उपयोग करने की अनुमति देते हैं, जिसके बाद स्वचालित रूप से परिवर्तन होता है। यह उन साइटों के लिए उपयोगी है जो प्रमाणीकरण की आवश्यकता होती हैं या कुकीज़ के माध्यम से सत्र की स्थिति को ट्रैक करते हैं। आप एक IP से कई पृष्ठों को पार्स कर सकते हैं, वास्तविक उपयोगकर्ता के व्यवहार की नकल करते हुए, और फिर IP स्वचालित रूप से बदल जाता है।

चिकित्सा साइटों के लिए 10-15 मिनट की अवधि के साथ स्टिकी सत्र का उपयोग करने की सिफारिश की जाती है। इस समय में आप 10-20 पृष्ठों को पार्स कर सकते हैं (देरी के आधार पर), जिसके बाद IP बदल जाता है, और आप "नया सत्र" शुरू करते हैं। यह स्वाभाविक रूप से दिखाई देता है और पहचान के जोखिम को कम करता है।

IP पते के पूल का आकार

दीर्घकालिक पार्सिंग के लिए उपलब्ध IP पते के पूल का आकार महत्वपूर्ण है। यदि आप एक ही सेट के 100 IP को एक सप्ताह के लिए उपयोग करते हैं, तो साइट पैटर्न को देख सकती है और इन सभी पते को ब्लॉक कर सकती है। रिज़िडेंट प्रॉक्सी आमतौर पर लाखों IP तक पहुंच प्रदान करते हैं, जो एक ही पते के पुन: उपयोग की संभावना को लगभग समाप्त कर देता है।

डेटा सेंटर प्रॉक्सी का उपयोग करते समय, औसत मात्रा (10,000-50,000 पृष्ठ प्रति माह) के पार्सिंग के लिए कम से कम 500-1000 IP का पूल होना चाहिए। बड़े पैमाने पर पार्सिंग (सैकड़ों हजारों पृष्ठ) के लिए, रिज़िडेंट प्रॉक्सी का उपयोग करना बेहतर होता है, जिनके पास विशाल IP पूल होते हैं।

विभिन्न स्रोतों के लिए रोटेशन के लिए सुझाव:

  • PubMed — रोटेशन अनिवार्य नहीं है, दर सीमा का पालन करते हुए 1 IP पर्याप्त है
  • वाणिज्यिक प्रकाशक — 10-15 मिनट के स्टिकी सत्र, 15-20 पृष्ठों के बाद नया IP
  • फार्मास्यूटिकल डेटाबेस — प्रत्येक अनुरोध के लिए रोटेशन या 5 मिनट के स्टिकी सत्र
  • Cloudflare के साथ साइटें — स्टिकी सत्र अनिवार्य हैं, अनुरोधों के स्तर पर रोटेशन काम नहीं करता

प्रॉक्सी के साथ पार्सिंग के लिए Python में कोड के उदाहरण

चिकित्सा डेटा के पार्सिंग के लिए प्रॉक्सी सेटअप के व्यावहारिक उदाहरणों पर विचार करें, जिसमें लोकप्रिय Python लाइब्रेरी का उपयोग किया गया है। हम एक बुनियादी उदाहरण से शुरू करेंगे और धीरे-धीरे इसे जटिल बनाएंगे।

requests लाइब्रेरी के साथ बुनियादी सेटअप

import requests
from time import sleep
import random

# प्रॉक्सी सेटअप (अपने डेटा से बदलें)
PROXY_HOST = "proxy.example.com"
PROXY_PORT = "8080"
PROXY_USER = "username"
PROXY_PASS = "password"

proxies = {
    'http': f'http://{PROXY_USER}:{PROXY_PASS}@{PROXY_HOST}:{PROXY_PORT}',
    'https': f'http://{PROXY_USER}:{PROXY_PASS}@{PROXY_HOST}:{PROXY_PORT}'
}

# वास्तविक ब्राउज़र की नकल करने के लिए हेडर
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
    'Accept-Language': 'en-US,en;q=0.9',
    'Accept-Encoding': 'gzip, deflate, br',
    'DNT': '1',
    'Connection': 'keep-alive',
    'Upgrade-Insecure-Requests': '1'
}

# PubMed के लिए अनुरोध का उदाहरण
url = "https://pubmed.ncbi.nlm.nih.gov/?term=diabetes"

try:
    response = requests.get(url, proxies=proxies, headers=headers, timeout=30)
    print(f"स्थिति कोड: {response.status_code}")
    print(f"सामग्री की लंबाई: {len(response.content)}")
    
    # अनुरोधों के बीच देरी जोड़ें (PubMed के लिए अनिवार्य)
    sleep(random.uniform(1.0, 3.0))
    
except requests.exceptions.RequestException as e:
    print(f"त्रुटि: {e}")

रोटेशन और पुनः प्रयास लॉजिक के साथ उन्नत सेटअप

import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
from time import sleep
import random

class ProxyRotator:
    def __init__(self, proxy_list):
        """
        proxy_list: प्रॉक्सी के साथ शब्दकोशों की सूची
        [{'http': 'http://user:pass@host:port', 'https': '...'}, ...]
        """
        self.proxy_list = proxy_list
        self.current_index = 0
    
    def get_next_proxy(self):
        """सूची से अगली प्रॉक्सी प्राप्त करें"""
        proxy = self.proxy_list[self.current_index]
        self.current_index = (self.current_index + 1) % len(self.proxy_list)
        return proxy

def create_session_with_retries():
    """त्रुटियों के मामले में स्वचालित पुनः प्रयास के साथ सत्र बनाएँ"""
    session = requests.Session()
    
    # स्वचालित पुनः प्रयास सेटअप
    retry_strategy = Retry(
        total=3,  # अधिकतम 3 प्रयास
        backoff_factor=1,  # प्रयासों के बीच देरी: 1, 2, 4 सेकंड
        status_forcelist=[429, 500, 502, 503, 504],  # पुनः प्रयास के लिए कोड
        allowed_methods=["GET", "POST"]
    )
    
    adapter = HTTPAdapter(max_retries=retry_strategy)
    session.mount("http://", adapter)
    session.mount("https://", adapter)
    
    return session

def scrape_with_rotation(urls, proxy_rotator):
    """प्रॉक्सी के साथ रोटेशन के साथ URL की सूची का पार्सिंग"""
    session = create_session_with_retries()
    results = []
    
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
        'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
        'Accept-Language': 'en-US,en;q=0.9',
    }
    
    for url in urls:
        # प्रत्येक अनुरोध के लिए नया प्रॉक्सी प्राप्त करें
        proxy = proxy_rotator.get_next_proxy()
        
        try:
            response = session.get(
                url, 
                proxies=proxy, 
                headers=headers, 
                timeout=30
            )
            
            if response.status_code == 200:
                results.append({
                    'url': url,
                    'status': 'सफल',
                    'content_length': len(response.content)
                })
                print(f"✓ सफल: {url}")
            else:
                results.append({
                    'url': url,
                    'status': 'विफल',
                    'error': f"स्थिति कोड: {response.status_code}"
                })
                print(f"✗ विफल: {url} (स्थिति: {response.status_code})")
        
        except requests.exceptions.RequestException as e:
            results.append({
                'url': url,
                'status': 'त्रुटि',
                'error': str(e)
            })
            print(f"✗ त्रुटि: {url} ({e})")
        
        # अनुरोधों के बीच यादृच्छिक देरी (महत्वपूर्ण!)
        sleep(random.uniform(2.0, 5.0))
    
    return results

# उपयोग का उदाहरण
proxy_list = [
    {
        'http': 'http://user1:pass1@proxy1.example.com:8080',
        'https': 'http://user1:pass1@proxy1.example.com:8080'
    },
    {
        'http': 'http://user2:pass2@proxy2.example.com:8080',
        'https': 'http://user2:pass2@proxy2.example.com:8080'
    }
]

rotator = ProxyRotator(proxy_list)

urls_to_scrape = [
    "https://pubmed.ncbi.nlm.nih.gov/?term=diabetes",
    "https://pubmed.ncbi.nlm.nih.gov/?term=cancer",
    "https://pubmed.ncbi.nlm.nih.gov/?term=covid"
]

results = scrape_with_rotation(urls_to_scrape, rotator)

JavaScript वाले साइटों के लिए Selenium का उपयोग

कई आधुनिक चिकित्सा साइटें सामग्री लोड करने के लिए JavaScript का उपयोग करती हैं। ऐसे मामलों में एक headless ब्राउज़र की आवश्यकता होती है:

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time

def create_proxy_driver(proxy_host, proxy_port, proxy_user, proxy_pass):
    """प्रॉक्सी के साथ Chrome WebDriver बनाएं"""
    
    chrome_options = Options()
    
    # Headless मोड (बिना GUI)
    chrome_options.add_argument('--headless')
    chrome_options.add_argument('--no-sandbox')
    chrome_options.add_argument('--disable-dev-shm-usage')
    
    # प्रॉक्सी सेटअप
    chrome_options.add_argument(f'--proxy-server=http://{proxy_host}:{proxy_port}')
    
    # स्वचालन को बंद करें (पहचान को बायपास करने के लिए महत्वपूर्ण)
    chrome_options.add_experimental_option("excludeSwitches", ["enable-automation"])
    chrome_options.add_experimental_option('useAutomationExtension', False)
    
    # User-Agent
    chrome_options.add_argument('--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36')
    
    driver = webdriver.Chrome(options=chrome_options)
    
    # प्रमाणीकरण के साथ प्रॉक्सी के लिए एक एक्सटेंशन का उपयोग करना आवश्यक है
    # या capabilities के माध्यम से सेटअप करना (जटिल विकल्प)
    
    return driver

def scrape_with_selenium(url, driver):
    """JavaScript लोडिंग की प्रतीक्षा करते हुए पृष्ठ का पार्सिंग"""
    
    driver.get(url)
    
    # तत्वों के लोड होने की प्रतीक्षा
    try:
        wait = WebDriverWait(driver, 10)
        results = wait.until(
            EC.presence_of_element_located((By.CLASS_NAME, "results-article"))
        )
        
        # डेटा निकालना
        articles = driver.find_elements(By.CLASS_NAME, "results-article")
        
        data = []
        for article in articles:
            try:
                title = article.find_element(By.CLASS_NAME, "docsum-title").text
                authors = article.find_element(By.CLASS_NAME, "docsum-authors").text
                
                data.append({
                    'title': title,
                    'authors': authors
                })
            except:
                continue
        
        return data
        
    except Exception as e:
        print(f"तत्वों की प्रतीक्षा करते समय त्रुटि: {e}")
        return []

# उपयोग का उदाहरण
proxy_host = "proxy.example.com"
proxy_port = "8080"
proxy_user = "username"
proxy_pass = "password"

driver = create_proxy_driver(proxy_host, proxy_port, proxy_user, proxy_pass)

try:
    url = "https://pubmed.ncbi.nlm.nih.gov/?term=diabetes"
    results = scrape_with_selenium(url, driver)
    
    for result in results:
        print(f"शीर्षक: {result['title']}")
        print(f"लेखक: {result['authors']}\n")
        
finally:
    driver.quit()

अनुरोधों की गति का नियंत्रण और दर सीमित करना बायपास करना

दर सीमित करना चिकित्सा साइटों के पार्सिंग के खिलाफ एक मुख्य सुरक्षा उपाय है। अनुरोधों की गति का सही सेटअप दीर्घकालिक पार्सिंग के लिए महत्वपूर्ण है, बिना ब्लॉक किए।

सुरक्षित गति निर्धारित करना

पहला कदम विशेष साइट के लिए सीमाओं को निर्धारित करना है। इसे प्रयोगात्मक रूप से किया जा सकता है, धीरे-धीरे अनुरोधों की गति बढ़ाते हुए जब तक 429 (बहुत अधिक अनुरोध) या ब्लॉकिंग त्रुटियां उत्पन्न न हों। अधिकांश चिकित्सा साइटों के लिए सुरक्षित मान:

  • PubMed — प्रति सेकंड अधिकतम 3 अनुरोध (आधिकारिक सिफारिश)
  • ClinicalTrials.gov — प्रति मिनट 20 अनुरोध सुरक्षित हैं, 5 मिनट में 100 तक स्वीकार्य हैं
  • वाणिज्यिक प्रकाशक — प्रति IP 10-15 अनुरोध
  • फार्मास्यूटिकल डेटाबेस — प्रति मिनट 5-10 अनुरोध

Python में दर सीमित करने वाले कोड का कार्यान्वयन

import time
from collections import deque

class RateLimiter:
    def __init__(self, max_calls, period):
        """
        max_calls: अधिकतम कॉल की संख्या
        period: समय अवधि सेकंड में
        उदाहरण: RateLimiter(3, 1) = प्रति सेकंड 3 अनुरोध
        """
        self.max_calls = max_calls
        self.period = period
        self.calls = deque()
    
    def __call__(self, func):
        """फंक्शन के कॉल की गति को सीमित करने के लिए डेकोरेटर"""
        def wrapper(*args, **kwargs):
            now = time.time()
            
            # अवधि के बाहर पुराने कॉल को हटा दें
            while self.calls and self.calls[0] < now - self.period:
                self.calls.popleft()
            
            # यदि सीमा तक पहुँच गए हैं, तो प्रतीक्षा करें
            if len(self.calls) >= self.max_calls:
                sleep_time = self.period - (now - self.calls[0])
                if sleep_time > 0:
                    print(f"दर सीमा तक पहुँच गई, सोते हुए {sleep_time:.2f}s")
                    time.sleep(sleep_time)
                    # प्रतीक्षा के बाद साफ करें
                    self.calls.clear()
            
            # कॉल के समय को रिकॉर्ड करें
            self.calls.append(time.time())
            
            # फंक्शन को निष्पादित करें
            return func(*args, **kwargs)
        
        return wrapper

# उपयोग का उदाहरण
@RateLimiter(max_calls=3, period=1)  # प्रति सेकंड 3 अनुरोध
def fetch_pubmed_page(url):
    response = requests.get(url, headers=headers, proxies=proxies)
    return response

# अब फंक्शन स्वचालित रूप से दर सीमा का पालन करता है
for i in range(10):
    result = fetch_pubmed_page(f"https://pubmed.ncbi.nlm.nih.gov/?term=test&page={i}")
    print(f"पृष्ठ {i} प्राप्त किया")

अनुकूलित दर सीमित करना

एक अधिक उन्नत दृष्टिकोण — सर्वर के उत्तरों के आधार पर गति को अनुकूलित करना। यदि 429 या 503 त्रुटियां प्राप्त होती हैं, तो स्वचालित रूप से गति को कम करें:

import time
import random

class AdaptiveRateLimiter:
    def __init__(self, initial_delay=1.0, max_delay=60.0):
        self.current_delay = initial_delay
        self.initial_delay = initial_delay
        self.max_delay = max_delay
        self.success_count = 0
    
    def wait(self):
        """अगले अनुरोध से पहले प्रतीक्षा करें"""
        # स्वाभाविकता के लिए यादृच्छिकता जोड़ें
        actual_delay = self.current_delay * random.uniform(0.8, 1.2)
        time.sleep(actual_delay)
    
    def on_success(self):
        """सफल अनुरोध पर कॉल किया जाता है"""
        self.success_count += 1
        
        # 10 सफल अनुरोधों के बाद थोड़ी तेजी लाएँ
        if self.success_count >= 10:
            self.current_delay = max(
                self.initial_delay,
                self.current_delay * 0.9
            )
            self.success_count = 0
    
    def on_rate_limit(self):
        """429 या समान त्रुटियों पर कॉल किया जाता है"""
        # देरी को दोगुना करें, लेकिन अधिकतम से अधिक नहीं
        self.current_delay = min(
            self.current_delay * 2,
            self.max_delay
        )
        self.success_count = 0
        print(f"दर सीमा हिट! देरी बढ़ाकर {self.current_delay:.2f}s कर दी गई")
    
    def on_error(self):
        """अन्य त्रुटियों पर कॉल किया जाता है"""
        # देरी को थोड़ा बढ़ाएं
        self.current_delay = min(
            self.current_delay * 1.5,
            self.max_delay
        )
        self.success_count = 0

# उपयोग का उदाहरण
limiter = AdaptiveRateLimiter(initial_delay=2.0, max_delay=30.0)

for url in urls_to_scrape:
    limiter.wait()
    
    try:
        response = requests.get(url, proxies=proxies, headers=headers)
        
        if response.status_code == 200:
            limiter.on_success()
            # डेटा को संसाधित करें
            
        elif response.status_code == 429:
            limiter.on_rate_limit()
            # बाद में पुनः प्रयास करें
            
        else:
            limiter.on_error()
            
    except requests.exceptions.RequestException:
        limiter.on_error()

चिकित्सा साइटों के लिए सही हेडर और User-Agent

चिकित्सा साइटें बॉट्स का पता लगाने के लिए HTTP हेडर का विश्लेषण करती हैं। गलत या अनुपस्थित हेडर गुणवत्ता प्रॉक्सी के उपयोग के बावजूद ब्लॉकिंग का एक सामान्य कारण है।

अनिवार्य हेडर

प्रत्येक अनुरोध में मौजूद होना चाहिए हेडरों का न्यूनतम सेट:

headers = {
    # User-Agent — हमेशा एक वर्तमान ब्राउज़र
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
    
    # Accept — ब्राउज़र द्वारा स्वीकार किए जाने वाले सामग्री प्रकार
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8',
    
    # Accept-Language — उपयोगकर्ता की भाषा
    'Accept-Language': 'en-US,en;q=0.9',
    
    # Accept-Encoding — संकुचन का समर्थन
    'Accept-Encoding': 'gzip, deflate, br',
    
    # Connection — कनेक्शन बनाए रखना
    'Connection': 'keep-alive',
    
    # Upgrade-Insecure-Requests — स्वचालित HTTPS पर स्विच
    'Upgrade-Insecure-Requests': '1',
    
    # DNT — Do Not Track (वैकल्पिक, लेकिन यथार्थता जोड़ता है)
    'DNT': '1',
    
    # Sec-Fetch-* हेडर (आधुनिक ब्राउज़रों के लिए महत्वपूर्ण)
    'Sec-Fetch-Dest': 'document',
    'Sec-Fetch-Mode': 'navigate',
    'Sec-Fetch-Site': 'none',
    'Sec-Fetch-User': '?1',
    
    # Cache-Control
    'Cache-Control': 'max-age=0'
}

User-Agent की रोटेशन

एक ही User-Agent का उपयोग संदिग्ध हो सकता है। कई वर्तमान ब्राउज़रों के बीच रोटेशन की सिफारिश की जाती है:

import random

USER_AGENTS = [
    # Windows पर Chrome
    'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
    
    # Mac पर Chrome
    'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
    
    # Windows पर Firefox
    'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:121.0) Gecko/20100101 Firefox/121.0',
    
    # Mac पर Firefox
    'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:121.0) Gecko/20100101 Firefox/121.0',
    
    # Mac पर Safari
    'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.1 Safari/605.1.15',
    
    # Windows पर Edge
    'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 Edg/120.0.0.0'
]

def get_random_headers():
    """यादृच्छिक User-Agent के साथ हेडर प्राप्त करें"""
    return {
        'User-Agent': random.choice(USER_AGENTS),
        'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
        'Accept-Language': 'en-US,en;q=0.9',
        'Accept-Encoding': 'gzip, deflate, br',
        'Connection': 'keep-alive',
        'Upgrade-Insecure-Requests': '1',
        'DNT': '1'
    }

# उपयोग
for url in urls:
    headers = get_random_headers()
    response = requests.get(url, headers=headers, proxies=proxies)

फार्मों के लिए Referer और Origin

खोज फ़ॉर्म के साथ काम करते समय या POST अनुरोध भेजते समय, Referer और Origin हेडर जोड़ना अनिवार्य है:

# खोज फ़ॉर्म के लिए POST अनुरोध
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
    'Accept-Language': 'en-US,en;q=0.9',
    'Accept-Encoding': 'gzip, deflate, br',
    'Content-Type': 'application/x-www-form-urlencoded',
    'Origin': 'https://example.com',
    'Referer': 'https://example.com/search',
    'Connection': 'keep-alive'
}

# फ़ॉर्म डेटा के साथ POST अनुरोध
data = {
    'query': 'diabetes',
    'page': '1'
}

response = requests.post(
    'https://example.com/search',
    headers=headers,
    data=data,
    proxies=proxies
)

विशिष्ट समस्याएं और उनका समाधान

चिकित्सा डेटा के पार्सिंग के दौरान विशिष्ट समस्याएं उत्पन्न होती हैं। आइए सबसे सामान्य समस्याओं और उनके समाधान पर विचार करें।

समस्या: Cloudflare सभी अनुरोधों को ब्लॉक करता है

लक्षण: "आपके ब्राउज़र की जांच" पाठ के साथ पृष्ठ प्राप्त करना या Cloudflare का उल्लेख करते हुए 403 Forbidden त्रुटि।

समाधान:

  • डेटा सेंटर के बजाय रिज़िडेंट प्रॉक्सी का उपयोग करें — Cloudflare डेटा सेंटर के IP को डिफ़ॉल्ट रूप से ब्लॉक करता है
  • Selenium या Puppeteer पर स्विच करें — headless ब्राउज़र Cloudflare की जांचों को बेहतर तरीके से पार करते हैं
  • Python के लिए cloudscraper लाइब्रेरी का उपयोग करें — यह स्वचालित रूप से Cloudflare की बुनियादी सुरक्षा को बायपास करती है
  • कुकीज़ और JavaScript को सक्षम करें — Cloudflare उनकी उपस्थिति की जांच करता है
  • TLS फिंगरप्रिंटिंग जोड़ें — असली ब्राउज़र की नकल करने के लिए curl_cffi का उपयोग करें

समस्या: 429 Too Many Requests त्रुटि प्राप्त कर रहा हूँ

लक्षण: कुछ सफल अनुरोधों के बाद, सर्वर 429 लौटाना शुरू करता है।

समाधान:

  • अनुरोधों के बीच देरी बढ़ाएं — 3-5 सेकंड से शुरू करने का प्रयास करें
  • IP रोटेशन सक्षम करें — प्रत्येक अनुरोध एक नए IP के माध्यम से दर सीमित करना हटा देता है
  • 429 उत्तर में Retry-After हेडर की जांच करें — यह बताता है कि कितने सेकंड प्रतीक्षा करनी है
  • पुनः प्रयासों में एक्सपोनेंशियल देरी का उपयोग करें — 1s, 2s, 4s, 8s आदि।

समस्या: प्रॉक्सी धीमी या अक्सर टूटती हैं

लक्षण: टाइमआउट त्रुटियाँ, पृष्ठों का बहुत धीमा लोड होना, कनेक्शन टूटना।

समाधान:

  • अनुरोधों में टाइमआउट को 30-60 सेकंड तक बढ़ाएं — रिज़िडेंट प्रॉक्सी धीमी हो सकती हैं
  • भौगोलिक रूप से निकट प्रॉक्सी का उपयोग करें — यदि आप एक यूरोपीय साइट को पार्स कर रहे हैं, तो यूरोपीय IP का उपयोग करें
  • प्रॉक्सी प्रदाता की गुणवत्ता की जांच करें — सस्ते प्रॉक्सी अक्सर अस्थिर होते हैं
  • पुनः प्रयास लॉजिक जोड़ें — कनेक्शन त्रुटि पर स्वचालित रूप से अनुरोध को पुनः प्रयास करें
  • कनेक्शन पूलिंग का उपयोग करें — requests.Session() के माध्यम से TCP कनेक्शनों का पुन: उपयोग करें

समस्या: साइट प्रमाणीकरण या सदस्यता की मांग करती है

लक्षण: लेखों के पूर्ण पाठों तक पहुंच सीमित है, लॉगिन की आवश्यकता है।

समाधान:

  • संस्थानात्मक पहुंच का उपयोग करें — कई विश्वविद्यालयों और अस्पतालों की सदस्यताएँ होती हैं
  • Open Access संस्करणों की उपलब्धता की जांच करें — कई लेख मुफ्त में रिपॉजिटरी के माध्यम से उपलब्ध होते हैं
  • पार्सिंग के बजाय API का उपयोग करें — कुछ प्रकाशक शोधकर्ताओं के लिए API प्रदान करते हैं
  • केवल मेटाडेटा (शीर्षक, लेखक, सारांश) पार्स करें — ये आमतौर पर मुफ्त में उपलब्ध होते हैं

समस्या: JavaScript सामग्री लोड नहीं हो रही है

लक्षण: HTML में आवश्यक डेटा नहीं है, केवल लोडिंग स्पिनर या खाली कंटेनर दिखाई देते हैं।

समाधान:

  • Selenium/Puppeteer पर स्विच करें — ये JavaScript को निष्पादित करते हैं
  • API एंडपॉइंट खोजें — ब्राउज़र में DevTools खोलें, नेटवर्क टैब, और डेटा के साथ XHR अनुरोधों को खोजें
  • requests-html का उपयोग करें — एक पुस्तकालय जो...
```