Python स्क्रैपर में cf_clearance Cookies का दोबारा इस्तेमाल कैसे करें

Cloudflare की चुनौती हल करना काम का सिर्फ़ आधा हिस्सा है। इसे हल करने पर आपको जो मिलता है वह है एक cf_clearance cookie, और यही cookie असल में अगली request को दोबारा चुनौती मिलने से रोकती है। यह जल्दी expire हो जाती है, यह ज़्यादातर लोगों की सोच से कहीं ज़्यादा चीज़ों से बँधी होती है, और यह काम करना तभी बंद कर देती है जब आपका client उससे अलग हो जाता है जिसने इसे कमाया था। यह पोस्ट बताती है कि यह cookie क्या है, इसे कैसे कैप्चर करें, कौन-सी चीज़ें चुपचाप इसे अमान्य कर देती हैं, और expired cookie को टूटी हुई cookie से कैसे अलग पहचानें।
आपको क्या चाहिए
- Python 3.10 या नया, साथ में session-सक्षम HTTP client। उदाहरण एक session इस्तेमाल करते हैं ताकि cookies requests के बीच बनी रहें।
- एक ऐसा टारगेट जो सच में कोई चुनौती जारी करता हो। जो साइट आपको कभी चुनौती नहीं देती वह कभी cookie सेट नहीं करेगी, इसलिए टेस्ट करने के लिए कुछ नहीं बचता।
- CapSkip चलता हुआ, चाहे Local mode में loopback पते पर हो या Server mode में किसी ऐसी मशीन पर जहाँ तक आपके workers पहुँच सकें। दोनों यहाँ बताए गए हैं: कनेक्शन सेटिंग्स। इसलिए शुरू करने से पहले एक चुन लें।
cf_clearance cookie असल में क्या है
यह एक रसीद है। Cloudflare का संदर्भ इसे उस cookie के रूप में बताता है जो चुनौती पास होने के प्रमाण को सेव करती है, जिसका इस्तेमाल इसलिए किया जाता है ताकि जब cookie मौजूद हो तो दोबारा कोई चुनौती जारी न हो। यह वही cookie भी है जिसमें JavaScript detections सेव होते हैं, और इसे SameSite None, Secure और Partitioned के साथ सेट किया जाता है ताकि यह स्थिति cross-site requests में भी बनी रहे।
इसकी अवधि आपके चुनने की चीज़ नहीं है। यह उस साइट की Challenge Passage सेटिंग से तय होती है जिस पर आप जा रहे हैं, और Cloudflare डिफ़ॉल्ट को साफ़ तौर पर दस्तावेज़ में दर्ज करता है: cf_clearance cookie की अवधि 30 मिनट होती है, और समझदारी भरी सीमा के तौर पर 15 से 45 मिनट का सुझाव दिया जाता है। कुछ साइटें इसे छोटा कर देती हैं। कुछ इसे बढ़ा देती हैं। आप बाहर से यह मान पढ़ नहीं सकते, इसलिए हर clearance को अल्पकालिक मानें और यह उम्मीद करने के बजाय कि यह टिकेगी, refresh के लिए तैयार रहें।
इससे तीन व्यावहारिक नतीजे निकलते हैं। आपको cookie को सँभालकर रखना चाहिए, क्योंकि हर request पर दोबारा हल करना धीमा और फ़िज़ूल है। आपको कभी यह नहीं मान लेना चाहिए कि यह restart के बाद भी बची रहेगी। और आपके पास एक ऐसा code path होना चाहिए जो यह पहचान ले कि यह पुरानी पड़ चुकी है और चुपचाप एक नई कमा ले।
स्टेप 1: चुनौती हल करें, फिर पूरे client को सँभाल कर रखें
सबसे पहले जिस ग़लती से बचना ज़रूरी है वह है token को इनाम समझना। यह इनाम नहीं है। Turnstile चुनौती हल करने पर मिलने वाला token वह चीज़ है जिसे आप clearance के बदले देते हैं, और जो cookie आपको वापस मिलती है वही असल में मूल्यवान चीज़ है। तो क्रम यह है: हल करें, सबमिट करें, फिर उस session को थामे रखें जिसे response मिला।
# pip install capskip
from capskip import CapSkip
solver = CapSkip(host="127.0.0.1", port=8080)
# A challenge page needs two more values than a plain widget does.
result = solver.turnstile(
sitekey="YOUR_SITEKEY",
url="https://example.com/protected",
data="YOUR_CDATA",
pagedata="YOUR_CHLPAGEDATA",
)
token = result["code"]
agent = result["userAgent"] # not optional, see the next sectionउस token को उसी तरह सबमिट करें जैसे ख़ुद पेज करता, और उस session से जिसे आप बनाए रखना चाहते हैं। response वापस आते ही, clearance cookie उस session के cookie jar में मौजूद होती है और आप इसे सीधे पढ़ सकते हैं।
# pip install requests
import requests
s = requests.Session()
s.headers["User-Agent"] = agent # the exact agent the solver returned
# ... submit the token here, exactly as the challenge page does ...
clearance = s.cookies.get("cf_clearance")
print(bool(clearance)) # True once the challenge is clearedस्टेप 2: जानें कि इसे चुपचाप कौन अमान्य कर देता है
Cloudflare सटीक बंधन को सार्वजनिक नहीं करता, इसलिए यह टेबल एक दस्तावेज़ीकृत अनुबंध नहीं बल्कि देखा गया व्यवहार है। यह इतना सुसंगत है कि इस पर भरोसा किया जा सके, और यहाँ की हर पंक्ति ने किसी न किसी का एक दोपहर बर्बाद किया है।
| क्या बदला | क्या clearance बची रहती है | क्यों |
|---|---|---|
| आपका user agent string | नहीं | clearance एक ख़ास ब्राउज़र पहचान को जारी की गई थी |
| आपका स्रोत IP पता | नहीं | किसी नए पते पर पहुँची cookie ही क्लासिक replay signature है |
| आपका TLS फ़िंगरप्रिंट | आमतौर पर नहीं | cookie से पहले handshake पढ़ी जाती है, इसलिए बेमेल पहले ही पकड़ में आ जाता है |
| वह hostname जिसे आप इसे भेजते हैं | नहीं | clearance प्रति साइट होती है, न कि प्रति खाता या प्रति नेटवर्क |
| समय बीतना | सिर्फ़ तब तक जब तक Challenge Passage समाप्त न हो | डिफ़ॉल्ट 30 मिनट है और साइट इसे बदल सकती है |
| असंबंधित cookies जोड़ना | हां | clearance जाँच अन्य cookies को अनदेखा कर देती है |
पहली तीन पंक्तियाँ असल में एक ही नियम के तीन रूप हैं: clearance किसी client की होती है, आपकी नहीं। इसलिए उस पहचान को स्थिर रखें जिसने इसे कमाया। मतलब उस cookie की पूरी उम्र के दौरान एक ही user agent, एक ही exit IP और एक ही TLS profile। session के बीच में proxy बदलना उस clearance को फेंक देना है जिसकी क़ीमत आप पहले ही चुका चुके हैं, और यही वह सबसे आम वजह है जिससे कोई चलता हुआ scraper बिना किसी दिखने वाली वजह के दोबारा चुनौती पाने लगता है।
यही वजह है कि सॉल्वर सिर्फ़ token के बजाय एक user agent भी वापस देता है। Turnstile token को उस ब्राउज़र पहचान से बाँध देता है जिसने उसे बनाया, इसलिए किसी अलग agent के तहत सबमिट किया गया token अस्वीकार हो जाता है, भले ही token अपने आप में बिल्कुल सही हो। लौटाए गए मान को जस का तस इस्तेमाल करें, और इसे हर उस request के लिए इस्तेमाल करते रहें जो नतीजे वाली cookie ले जाती है। Turnstile चुनौती पेज walkthrough यह दिखाता है कि दो अतिरिक्त इनपुट मान कहाँ से आते हैं, जो कि वह दूसरा आधा हिस्सा है जिसमें लोग ग़लती करते हैं।
स्टेप 3: इसे runs के बीच बनाए रखें
एक clearance cookie जो आपकी process के साथ ही ख़त्म हो जाती है, उस cookie से कहीं कम मूल्य की होती है जो restart के बाद भी बची रहती है। cookie jar को उस पहचान के साथ सेव करें जो उसके साथ जुड़ी है, क्योंकि अगर आप इसे किसी अलग agent या अलग proxy के तहत दोबारा लोड करते हैं तो अकेली cookie बेकार है।
# pip install requests
import json, time
def save_clearance(session, agent, proxy, path="clearance.json"):
"""Store the cookie with the identity that earned it."""
blob = {
"cf_clearance": session.cookies.get("cf_clearance"),
"user_agent": agent,
"proxy": proxy,
"stored_at": time.time(),
}
with open(path, "w") as fh:
json.dump(blob, fh)दोबारा लोड करना इसका उल्टा प्रतिबिंब है, बस एक अतिरिक्त जाँच के साथ। चुनौती मिलने का इंतज़ार करने के बजाय ख़ुद ही रिकॉर्ड को समय पर हटा दें, क्योंकि proactive refresh की क़ीमत सिर्फ़ एक हल है, जबकि reactive refresh पहले एक विफल request की क़ीमत चुकाता है।
# pip install requests
import json, time, requests
def load_clearance(path="clearance.json", max_age=900):
"""Return a ready session, or None if the record is too old."""
with open(path) as fh:
blob = json.load(fh)
# 15 minutes, comfortably inside a 30 minute default.
if time.time() - blob["stored_at"] > max_age:
return None
s = requests.Session()
s.headers["User-Agent"] = blob["user_agent"]
s.proxies = {"https": blob["proxy"]} if blob["proxy"] else {}
s.cookies.set("cf_clearance", blob["cf_clearance"])
return sपंद्रह मिनट जान-बूझकर रखी गई एक सतर्क ऊपरी सीमा है। आप वह Challenge Passage मान नहीं देख सकते जो किसी साइट ने कॉन्फ़िगर किया है, डिफ़ॉल्ट 30 मिनट है, और आधे रास्ते में refresh करने की क़ीमत सिर्फ़ एक सस्ता हल है, न कि एक टूटा हुआ batch। अगर सॉल्वर आपके अपने hardware पर बिना किसी प्रति-हल शुल्क के चलता है, तो जल्दी करना मुफ़्त है।
स्टेप 4: बिना अंदाज़ा लगाए पुरानी पड़ चुकी clearance पहचानें
एक मरी हुई clearance ख़ुद को किसी साफ़ error के ज़रिए सामने नहीं लाती। आमतौर पर आपको एक सामान्य दिखने वाला 403 मिलेगा, या एक 200 जिसके साथ वह JSON नहीं बल्कि एक HTML interstitial आएगा जो आपने माँगा था। सिर्फ़ status code जाँचने से दूसरा मामला पकड़ में नहीं आएगा, और सिर्फ़ status codes देखने वाला retry loop इस पर ख़ुशी-ख़ुशी हमेशा के लिए लूप करता रहेगा।
# pip install requests
def needs_new_clearance(response):
"""True when this response is a challenge rather than content."""
if response.status_code in (403, 503):
return True
body = response.text[:4000].lower()
markers = ("cf-turnstile", "challenge-platform", "just a moment")
return any(m in body for m in markers)इसे अपने parser के आगे लगाएँ, पीछे नहीं। जब यह true लौटाए, तो सेव किए गए रिकॉर्ड को हटा दें, एक बार हल करें, और नई session के साथ दोबारा कोशिश करें। पुरानी cookie के साथ ज़्यादा लंबी नींद लेकर दोबारा कोशिश न करें, क्योंकि इसमें समय की कोई गड़बड़ी नहीं है। यही अंतर reCAPTCHA tokens में भी दिखता है, जहाँ expiry की खिड़की और भी छोटी होती है। इस पर एक पोस्ट है: reCAPTCHA token कितनी देर तक वैध रहता है , जो उस पहलू को कवर करती है।
सॉल्वर को उसकी जगह सर्वर पर चलाना
Clearance cookies प्रति पहचान होती हैं, इसलिए workers के एक fleet को clearances के एक fleet की ज़रूरत होती है, और इनमें से हर एक को हल करना पड़ता है। यह काम worker पर ही होना ज़रूरी नहीं है। कनेक्शन सेटिंग्स दोनों तरीक़ों को कवर करती हैं:
| मोड | किस पर सुनता है | कब इस्तेमाल करें |
|---|---|---|
| लोकल | 127.0.0.1, केवल उसी डिवाइस पर | आपका स्क्रैपर और सॉल्वर एक ही मशीन पर चलते हैं |
| सर्वर | आपका नेटवर्क पता या पब्लिक IP | Workers, कोई VPS या होस्टेड प्लेटफ़ॉर्म API के ज़रिए कॉल करते हैं |
SDK के host को सॉल्वर मशीन की ओर इंगित करें और आपके कोड में और कुछ नहीं बदलता, इसलिए बीस workers एक ही instance साझा कर सकते हैं जबकि हर एक अपना अलग cookie jar रखता है। जब callers आपके अपने नेटवर्क से बाहर हों तो एक static public IP की सलाह दी जाती है। जानकारी यहाँ मिलती है: कनेक्शन सेटिंग्स, और Server mode फिर भी आपका ही hardware है और फिर भी अनमीटर्ड है: यह सिर्फ़ यह बदलता है कि सॉल्वर कहाँ चलता है, कभी यह नहीं कि इसका मालिक कौन है।
FAQ
एक cf_clearance cookie कितनी देर तक चलती है?
डिफ़ॉल्ट रूप से तीस मिनट, और साइट का मालिक इसे बदल सकता है। Cloudflare इसे Challenge Passage सेटिंग के रूप में उपलब्ध कराता है और इसे 15 से 45 मिनट के बीच रखने का सुझाव देता है, इसलिए आपको मिलने वाली ज़्यादातर साइटें इसी दायरे में कहीं होंगी। आप कॉन्फ़िगर किया गया मान बाहर से नहीं पढ़ सकते, यही वजह है कि अपने नियंत्रण वाले टाइमर पर refresh करना दोबारा चुनौती मिलने का इंतज़ार करने से बेहतर है।
क्या मैं एक clearance cookie कई workers के बीच साझा कर सकता हूँ?
सिर्फ़ तभी जब वे उस पहचान को साझा करें जिसने इसे कमाया, जिसका व्यवहार में मतलब है वही exit IP, वही user agent और वही TLS profile। यह एक ही proxy के पीछे हासिल किया जा सकता है, और यह हल बचाने का एक अच्छा तरीक़ा है। जिस पल दो workers अलग-अलग exit पते इस्तेमाल करते हैं, साझा cookie उनमें से एक के लिए विफल होने लगती है, और विफलताएँ बेतरतीब लगती हैं जब तक आप यह न देखें कि वे किस worker पर पड़ रही हैं।
मेरे proxies रोटेट करने के बाद मेरी clearance ने काम करना क्यों बंद कर दिया?
क्योंकि clearance पुराने पते को जारी की गई थी। किसी नए IP से आने वाली cookie बिल्कुल वही पैटर्न है जिसे पकड़ने के लिए replay protection मौजूद है, इसलिए इसे हटा दिया जाता है और आपको दोबारा चुनौती मिलती है। इसके बजाय session की सीमा पर रोटेट करें: एक proxy एक clearance कमाता है, इसे तब तक इस्तेमाल करता है जब तक यह समाप्त न हो जाए, और अगली session एक नए पते और एक नए हल के साथ ताज़ा शुरू होती है।
क्या मुझे clearance cookie रखने के लिए असली ब्राउज़र की ज़रूरत है?
नहीं। cookie jar वाला कोई भी HTTP client इसे ले जा सकता है, बशर्ते इसके आस-पास की पहचान स्थिर बनी रहे। एक ब्राउज़र आपको मुफ़्त में जो देता है वह है एक भरोसेमंद TLS handshake और एक भरोसेमंद header क्रम, और एक सामान्य HTTP client में डिफ़ॉल्ट रूप से इनमें से कोई नहीं होता। तो cookie मुश्किल हिस्सा नहीं है, स्थिरता है, और एक impersonating client ब्राउज़र की memory क़ीमत चुकाए बिना इसे पूरा कर देता है।
सबसे छोटा जवाब
cf_clearance cookie को एक client से बँधी अल्पकालिक रसीद मानें। इसे उस session से कैप्चर करें जिसने चुनौती पास की, इसे उस user agent और proxy के साथ सेव करें जिसने इसे कमाया, और ब्लॉक होने का इंतज़ार करने के बजाय लगभग पंद्रह मिनट के टाइमर पर refresh करें। सिर्फ़ status code नहीं बल्कि body भी जाँचें, क्योंकि चुनौती एक बिल्कुल स्वस्थ 200 के साथ भी आ सकती है। जब यह वाक़ई expire हो जाए, तो एक ताज़ा हल ही पूरा समाधान है, और एक कैप्चा सॉल्वर जो आपके अपने hardware पर चलता है, यह इतना सस्ता है कि इसे जल्दी किया जा सके। Turnstile solve जिन दो इनपुट रूपों में हो सकता है, उनके लिए पढ़ें Cloudflare Turnstile सॉल्वर पेज इससे पहले कि आप कुछ भी जोड़ें। Worker-pool में जोड़ने का तरीक़ा अलग से यहाँ कवर किया गया है: वेब स्क्रैपिंग के लिए कैप्चा सॉल्वर, जो बीस मिनट ख़र्च करने लायक़ है अगर आप एक से ज़्यादा worker चलाते हैं।
