बिना ब्लॉक हुए स्क्रैप करें: कोड के साथ एक व्यावहारिक गाइड
स्क्रैपिंग के दौरान ब्लॉक होने का मतलब आम तौर पर तीन में से एक चीज़ होती है: आपने बहुत ज़्यादा रिक्वेस्ट बहुत तेज़ी से भेजीं, आपका क्लाइंट किसी ज्ञात ब्राउज़र या बॉट जैसा बिल्कुल नहीं दिखा, या आपका IP पता उस सूची में है जिस पर साइट कम भरोसा करती है। इन तीनों को कुछ आदतों से कम किया जा सकता है: ब्लॉक को जल्दी पहचानना, साइट के पीछे हटने पर धीमा होना, एक सुसंगत और ईमानदार पहचान रखना, और प्रॉक्सी केवल वहीं इस्तेमाल करना जहां वह उचित हो। यह गाइड हर एक को काम करने वाले कोड के साथ समझाती है। इसे उन्हीं साइटों के लिए इस्तेमाल करें जिन्हें स्क्रैप करने की आपको अनुमति है।
ब्लॉक को पहचानें
ब्लॉक हमेशा एरर पेज जैसा नहीं दिखता। इन पर नज़र रखें:
- 403 Forbidden, जिसका अक्सर मतलब होता है कि साइट ने आपके क्लाइंट को मना कर दिया है। रुकें और दोबारा कोशिश करने से पहले जांचें कि क्या आपको वहां होने की अनुमति है।
- 429 Too Many Requests, जिसका मतलब है कि आप बहुत ज़्यादा भेज रहे हैं। इसके साथ अक्सर
Retry-Afterहेडर आता है। - 503 Service Unavailable, जिसका मतलब हो सकता है कि साइट पर लोड ज़्यादा है। पीछे हटें।
- लगभग बिना कंटेंट वाला 200 रिस्पॉन्स, लॉगिन या चैलेंज पेज पर रीडायरेक्ट, या ऐसा पेज जिसमें वह डेटा नहीं है जिसकी आपको उम्मीद थी।
हर विफलता के लिए स्टेटस कोड और बॉडी का एक छोटा नमूना लॉग करें। जो ब्लॉक आपके लॉग में नहीं दिखता, उसे आप ठीक भी नहीं कर सकते।
रिट्राई के साथ backoff करें
जब साइट कहे "धीमे चलो", तो आपके कोड को थोड़ा नहीं, काफी ज़्यादा धीमा होना चाहिए। कोशिशों की सीमा के साथ exponential backoff मानक तरीका है। साइट Retry-After भेजे तो यह उसका भी सम्मान करता है:
import time
import requests
session = requests.Session()
session.headers.update({
"User-Agent": "ExampleBot/1.0 (+https://example.com/bot)",
"Accept-Language": "en-US,en;q=0.9",
})
def polite_get(url: str, max_attempts: int = 4) -> requests.Response:
delay = 2.0
resp = None
for _ in range(max_attempts):
resp = session.get(url, timeout=30)
if resp.status_code not in (429, 503):
return resp
retry_after = resp.headers.get("Retry-After", "")
wait = float(retry_after) if retry_after.isdigit() else delay
time.sleep(wait)
delay *= 2
return resp # अब भी ब्लॉक: आखिरी रिस्पॉन्स लौटाएं ताकि कॉलर उसे संभाल सके
resp = polite_get("https://example.com/products?page=1")
print(resp.status_code, len(resp.text))
ध्यान दें कि यह फ़ंक्शन क्या नहीं करता। यह 403 को रिट्राई नहीं करता, और एक ब्लॉक से निकलने के लिए पहचानों के बीच घूमता भी नहीं। 403 रुकने का फैसला है, हल करने वाली पहेली नहीं।
ब्लॉक का चरण-दर-चरण निदान करें
जब कोई रन विफल होने लगे, तो कुछ और बदलने से पहले ये जांचें:
- पहले विफल URL और उसके स्टेटस कोड को देखें। ब्लॉक आम तौर पर किसी खास बिंदु से शुरू होता है, बेतरतीब तरीके से नहीं।
- पहली विफलता से पहले के मिनटों में रिक्वेस्ट दर देखें। बाढ़ सबसे आम कारण है।
- जांचें कि विफलता किसी एक पाथ, एक सेक्शन या दिन के एक समय से जुड़ी है या नहीं।
- उसी URL को एक सामान्य ब्राउज़र में हाथ से एक बार लाएं। अगर ब्राउज़र उसे लोड कर लेता है, तो फर्क आपके रिक्वेस्ट पैटर्न में है। अगर ब्राउज़र भी ब्लॉक है, तो साइट ने फिलहाल आपको वह पेज देना बंद कर दिया है।
- केवल तभी कोड बदलें। पहले धीमे हों, दूसरा backoff जोड़ें, और पहचान की समीक्षा सबसे आखिर में करें।
एक साथ कई चीज़ें बदलने से यह जानना असंभव हो जाता है कि किसने मदद की।
एक सुसंगत, ईमानदार पहचान रखें
स्क्रैपर तब ब्लॉक होते हैं जब उनकी पहचान रिक्वेस्ट के बीच बदलती है, या बाकी ट्रैफ़िक से मेल नहीं खाती। एक स्पष्ट User-Agent वाला एक सत्र सबसे सरल स्थिर पहचान है। अपने बॉट का नाम रखें, एक संपर्क लिंक जोड़ें, और केवल वही हेडर भेजें जो एक सामान्य क्लाइंट भेजता। कई अलग-अलग विज़िटर जैसा दिखने के लिए User-Agent बदलना बचने का एक रूप है, और यह ब्लॉक को कम नहीं, ज़्यादा संभावित बनाता है।
अगर कोई साइट ब्राउज़र और सादे HTTP क्लाइंट को अलग कंटेंट देती है, तो उन पेजों के लिए असली ब्राउज़र इस्तेमाल करें और वही रेट लिमिट रखें। यह एक वैध रास्ता है, और यह रिक्वेस्ट पैटर्न को समझदार रखता है।
प्रॉक्सी सावधानी से इस्तेमाल करें
प्रॉक्सी उस पते को बदल देती है जहां से रिक्वेस्ट आती है। यह वैध ज़रूरतों के लिए एक उपकरण है, जैसे उस साइट पर जिसे टेस्ट करने की आपको अनुमति है वहां किसी खास क्षेत्र से टेस्ट करना, या अपने ही इन्फ्रास्ट्रक्चर में लोड बांटना। यह उस सीमा से बचने का तरीका नहीं है जो साइट ने आप पर लगाई है। प्रॉक्सी का फ़ॉर्मेट वही है जो प्रॉक्सी टास्क टाइप इस्तेमाल करते हैं:
proxies = {
"http": "http://user:pass@proxy.example.net:8000",
"https": "http://user:pass@proxy.example.net:8000",
}
resp = session.get("https://example.com/products", proxies=proxies, timeout=30)
प्रॉक्सी का प्रकार चुनना एक अलग सवाल है, जिसे रेज़िडेंशियल बनाम डेटासेंटर प्रॉक्सी और स्क्रैपिंग के लिए रोटेटिंग प्रॉक्सी में समझाया गया है।
जब ब्लॉक कैप्चा बन जाए
कुछ साइटें रेट समस्या का जवाब कठोर ब्लॉक के बजाय कैप्चा से देती हैं। सही क्रम है: रुकें, धीमे हों, नियम दोबारा जांचें, और केवल तब सॉल्व पर विचार करें। PopularCaptcha विजेट के लिए Scarnox का लाइव API एक टोकन लौटाता है जिसे आप h-captcha-response फ़ील्ड में सबमिट करते हैं। दूसरे कैप्चा टाइप के लिए लाइव सूची देखें, क्योंकि reCAPTCHA, Cloudflare Turnstile, GeeTest, AWS WAF और Arkose का सपोर्ट जल्द आ रहा है। विस्तृत गाइड वेब स्क्रैपिंग और कैप्चा है।
अगर किसी साइट पर आपको ब्लॉक दिखने लगें, तो कारण लगभग हमेशा रिक्वेस्ट पैटर्न होता है। स्क्रैपिंग में कैप्चा से बचें उन आदतों को समझाती है जो इसे रोकती हैं।
ज़िम्मेदारी से स्क्रैप करें
- शुरू करने से पहले
robots.txtऔर साइट की शर्तें जांचें, और जो पाथ और देरी वे मांगें उनका पालन करें। - 403 या स्पष्ट "स्क्रैप न करें" संदेश मिलने पर रुकें। लगातार कोशिश न करते रहें।
- अपनी दर इतनी कम रखें कि एक सामान्य विज़िटर आपके ट्रैफ़िक को न देखे।
- जिस व्यक्तिगत डेटा को रखने का कोई कारण नहीं, उसे इकट्ठा न करें, और जो इकट्ठा करें उसे लागू होने वाले गोपनीयता नियमों के तहत संभालें।
- अगर आपको साइट की सहज क्षमता से कहीं ज़्यादा मात्रा चाहिए, तो मालिक से फ़ीड या API मांगें।