Back to Blog

पार्सर खाली फ़ील्ड दे रहा है, और प्रॉक्सी का कोई दोष नहीं: लेआउट ड्रिफ्ट को ठीक करें

पार्सर ने खाली परिणाम लौटाया, आप प्रॉक्सी बदल रहे हैं - जबकि समस्या साइट के री-डिजाइन में थी। हम समझते हैं कि कैसे पांच मिनट में बैन और ड्रिफ्टिंग लेआउट में अंतर करें, Scrapling के अनुकूलनशील चयनकर्ताओं का काम कैसे करता है (SQLite में तत्व का प्रिंट और समानता के आधार पर खोज 2.46 मि.से.) और क्यों मानक को उसी भूगोल से लेना चाहिए, जिससे आप बाद में डेटा इकट्ठा करते हैं।

📅September 5, 2026
पार्सर खाली फ़ील्ड दे रहा है, और प्रॉक्सी का कोई दोष नहीं: लेआउट ड्रिफ्ट को ठीक करें

पार्सर छह महीने तक काम कर रहा था, और आज डेटाबेस में खाली पंक्तियाँ आ गईं। पहला विचार - बैन हो गया, प्रॉक्सी बदलनी होगी। आप पूल बदलते हैं, आईपी की गुणवत्ता बढ़ाते हैं, डेटा सेंटर के बजाय रेजिडेंशियल के लिए भुगतान करते हैं - फिर भी फील्ड खाली हैं। क्योंकि समस्या बैन में नहीं थी: साइट ने नई लेआउट पर स्विच किया, और आपका CSS-सेलेक्टर अब किसी चीज़ से जुड़ा नहीं है।

यह सबसे महंगा प्रकार की खराबी है, क्योंकि यह चुप है। बैन तुरंत दिखाई देता है: 403, कैप्चा, रीडायरेक्ट। लेआउट में बदलाव कुछ नहीं गिराता - HTTP 200, पृष्ठ प्राप्त हुआ, ट्रैफ़िक का भुगतान किया गया, और आउटपुट None है। आइए समझते हैं कि कैसे पांच मिनट में एक को दूसरे से अलग करें और हर रीडिज़ाइन के बाद सेलेक्टर्स को मैन्युअल रूप से फिर से लिखना बंद करें।

किसे इसकी आवश्यकता है

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

समस्या का पैमाना काल्पनिक नहीं है। GroupBWT के विश्लेषकों के अनुसार, वेबसाइटों में अनियंत्रित संरचनात्मक परिवर्तन लगभग 40–60% दोहराए जाने वाले समर्थन लागत का कारण बनते हैं बड़े प्रोजेक्ट्स में। कुछ उद्योगों में 10–15% क्रॉलर हर सप्ताह मरम्मत की आवश्यकता होती है - DOM में बदलाव, फिंगरप्रिंटिंग और एंडपॉइंट्स की थ्रॉटलिंग के कारण। इसका मतलब है कि सेलेक्टर्स की मरम्मत एंटी-बॉट को बायपास करने की लागत के साथ प्रतिस्पर्धा करती है, जबकि इस पर ध्यान देने की मात्रा कई गुना कम होती है।

पृष्ठभूमि में स्थिति अच्छी नहीं है: Apify की रिपोर्ट "State of Web Scraping 2026" में 65.8% उत्तरदाताओं ने प्रॉक्सी के उपयोग में वृद्धि की, 58.3% ने वर्ष दर वर्ष प्रॉक्सी पर खर्च में वृद्धि की, और 62% ने मुख्य रूप से बॉट्स के खिलाफ बढ़ती सुरक्षा के कारण सामान्य बुनियादी ढांचे की लागत में वृद्धि की। इस पृष्ठभूमि में, उन पृष्ठों पर भुगतान किए गए ट्रैफ़िक को जलाना, जिनसे आप फिर भी कुछ नहीं निकालते, - यह दो बार निराशाजनक है।

चरण 1. बैन और लेआउट में बदलाव को अलग करना

निदान में कुछ मिनट लगते हैं और इसे क्रम में किया जाना चाहिए - अन्यथा आप आसानी से "गलत" खराबी को "मरम्मत" कर सकते हैं।

  1. उत्तर कोड और शरीर के आकार पर नज़र डालें। 403, 429, 503, जांच पृष्ठ पर रीडायरेक्ट या 2-5 केबी का शरीर - यह एंटी-बॉट है। HTTP 200 और 200-800 केबी का पूरा पृष्ठ - साइट ने आपको अनुमति दी, समस्या प्रॉक्सी में नहीं है।
  2. कच्चा HTML डिस्क पर सहेजें और इसे अपनी आँखों से खोलें। डिबगर में नहीं, बल्कि ब्राउज़र में। यदि उत्पाद/समीक्षा/कीमत सही जगह पर है, और पार्सर उन्हें नहीं देखता - तो यह लेआउट में बदलाव है।
  3. फाइल में खोज करके आवश्यक पाठ खोजें। यदि HTML में है, लेकिन आपके सेलेक्टर द्वारा उपलब्ध नहीं है - तो मार्कअप बदल गया है। यदि बिल्कुल नहीं है - सामग्री स्क्रिप्ट द्वारा लोड की जाती है, ब्राउज़र इंजन की आवश्यकता है, न कि HTTP अनुरोध की।
  4. पिछली सफल निकासी के साथ तुलना करें। एक ही URL के पुराने और नए HTML की तुलना करें: आमतौर पर तुरंत नया क्लास-रैपर, स्थानांतरित ब्लॉक या id को data-* में बदलने के लिए देखा जा सकता है।
  5. जांचें कि क्या साइट ने आपको पृष्ठ का कोई अन्य संस्करण नहीं दिया। इसके बारे में - नीचे अलग से, क्योंकि यहां प्रॉक्सी का कुछ संबंध है।

यदि तीसरे बिंदु के बाद निदान "मार्कअप चला गया" है, तो प्रॉक्सी बदलना बेकार है। एक पार्सर की आवश्यकता है जो तत्व को खोजने में सक्षम हो, भले ही सेलेक्टर पुराना हो गया हो।

चरण 2. अनुकूलनीय सेलेक्टर्स क्या हैं

विचार सरल है: .product-card > h3.title की पंक्ति से मजबूती से बंधने के बजाय, पुस्तकालय एक बार आवश्यक तत्व का "चित्र" याद रखता है, और अगली बार सबसे समान तत्व को पृष्ठ पर खोजता है।

यह सबसे व्यावहारिक रूप से Scrapling में लागू किया गया है - करीम शोआइर का ओपन-पायथन फ्रेमवर्क। प्रोजेक्ट अक्टूबर 2024 में लॉन्च हुआ और सितंबर 2026 तक GitHub पर 78,000 से अधिक सितारे इकट्ठा कर लिए; लेखन के समय का अंतिम रिलीज़ - v0.4.15 23 अगस्त 2026, कमिट्स रोजाना होते हैं। Python 3.10+ की आवश्यकता है।

अनुकूलनीय खोज की कार्यप्रणाली इस प्रकार है। जब आप auto_save=True के साथ सेलेक्टर को कॉल करते हैं, Scrapling तत्व का फिंगरप्रिंट सहेजता है:

  • टैग का नाम, पाठ और सभी विशेषताएँ उनके मानों के साथ;
  • पड़ोसी टैग के नाम;
  • तत्व तक पहुँच - केवल टैग के नामों के द्वारा;
  • पैरेंट का टैग, विशेषताएँ और पाठ।

फिंगरप्रिंट को स्थानीय SQLite डेटाबेस में रखा जाता है और "डोमेन + पहचानकर्ता" के जोड़े द्वारा कुंजीबद्ध किया जाता है। डोमेन पृष्ठ के URL से लिया जाता है (या adaptive_domain पैरामीटर द्वारा सेट किया जाता है), पहचानकर्ता डिफ़ॉल्ट रूप से स्वयं सेलेक्टर की पंक्ति होती है - या आपका खुद का, यदि identifier= दिया जाए।

जब लेआउट बदलता है और सामान्य सेलेक्टर खाली लौटाता है, तो adaptive=True के साथ कॉल सहेजे गए फिंगरप्रिंट को उठाता है और पृष्ठ के सभी तत्वों पर चलाता है, समानता का एक अस्पष्ट आकलन करते हुए - विशेषताओं के क्रम तक। सबसे अधिक मेल खाने वाला तत्व लौटाया जाता है।

यह सस्ता है। प्रोजेक्ट के आधिकारिक बेंचमार्क के अनुसार, पार्सिंग 1.99 मि.सेक लेती है जबकि Parsel/Scrapy के लिए 2.01 मि.सेक, PyQuery के लिए 22.93 मि.सेक, Selectolax के लिए 80.57 मि.सेक और BeautifulSoup के लिए 1541 मि.सेक। समान तत्व की अनुकूलनीय खोज - 2.46 मि.सेक AutoScraper के 13.3 मि.सेक के मुकाबले। इसका मतलब है कि रीडिज़ाइन से सुरक्षा अनुरोध में लगभग दो मिलीसेकंड जोड़ती है, जबकि नेटवर्क विलंबता सैकड़ों मिलीसेकंड में होती है।

चरण 3. स्थापित करें और चालू करें

स्थापना इस बात पर निर्भर करती है कि आपको ब्राउज़र की आवश्यकता है या नहीं:

  1. pip install scrapling - केवल पार्सर, बिना नेटवर्क भाग के। यदि आप HTML अपने कोड से प्राप्त करते हैं, तो यह पर्याप्त है।
  2. pip install "scrapling[fetchers]", फिर scrapling install - फेचर्स जोड़ता है और निर्भरताओं के साथ ब्राउज़र डाउनलोड करता है।
  3. अतिरिक्त: [ai] - MCP-सर्वर, [rag] - RAG के लिए बाइंडिंग, [shell] - इंटरैक्टिव कंसोल, [all] - सब कुछ एक साथ। एक तैयार छवि pyd4vinci/scrapling है।

इसके बाद - दो रन। पहला जीवित कार्यशील लेआउट पर फिंगरप्रिंट सहेजता है, दूसरा पहले से रीडिज़ाइन को सहन करने में सक्षम है:

  1. मानक रन। एक Selector ऑब्जेक्ट बनाएं जिसमें adaptive=True हो और url को अनिवार्य रूप से पास करें - अन्यथा डोमेन कुंजी "default" में चला जाएगा, और विभिन्न साइटों के फिंगरप्रिंट मिश्रित हो जाएंगे। आवश्यक सेलेक्टर को auto_save=True के साथ कॉल करें।
  2. बोर्ड रन। वही सेलेक्टर, लेकिन adaptive=True के साथ। जब तक मार्कअप सही है, सामान्य मार्ग काम करेगा। जब यह टूट जाएगा - समानता की खोज चालू हो जाएगी।
  3. भिन्नताओं को लॉग करें। वह क्षण जब सामान्य सेलेक्टर ने खाली दिया, जबकि अनुकूलनीय ने कुछ पाया, - यह "साइट चली गई" का संकेत है, इसे निगरानी में देखना चाहिए, न कि चुपचाप निगलना।

पुनर्लेखन के बारे में एक महत्वपूर्ण विवरण: सहेजना जमा नहीं होता है। उसी "डोमेन + पहचानकर्ता" के लिए पुनरावृत्त auto_save पिछले फिंगरप्रिंट को ओवरराइट करता है। इसलिए मानक को एक निश्चित रूप से सही पृष्ठ पर लिया जाता है, न कि सभी URL के पूल में लूप में।

चरण 4. प्रॉक्सी: वे किस तरह से संबंधित हैं

हमने इस बात से शुरुआत की कि लेआउट में बदलाव प्रॉक्सी के बारे में नहीं है। यह आधे सच है, और दूसरी आधी बात पैसे की है।

साइट आपको प्रॉक्सी के बाहर निकलने के कारण अलग मार्कअप दे सकती है। स्थान, भाषा और देश पृष्ठ के टेम्पलेट को बदलते हैं: ब्लॉकों का अलग क्रम, अलग क्लास, अलग कीमतों और तिथियों के प्रारूप। यह कोई परिकल्पना नहीं है - Scrapling में एक उदाहरण सुधार है: संस्करण 0.4.12 में StealthyFetcher से मजबूरित स्थानीयकरण en-US को हटा दिया गया, क्योंकि थोपे गए स्थानीयकरण वास्तविक भूगोल के साथ मेल नहीं खा रहे थे और व्यवहार को तोड़ रहे थे। यहां से एक कार्यशील नियम: मानक फिंगरप्रिंट उसी भूगोल से लें, जिससे आप बाद में डेटा एकत्र करते हैं. जर्मन आईपी के माध्यम से लिया गया फिंगरप्रिंट ब्राजीलियन से प्राप्त पृष्ठ के साथ मेल नहीं खाएगा - और आप "साइट ने लेआउट बदल दिया" की झूठी चेतावनी प्राप्त करेंगे।

व्यावहारिक परिणाम:

  • यदि पूल बहु-देशीय है - adaptive_domain के माध्यम से फिंगरप्रिंट को विभाजित करें, वहां "डोमेन + देश" जैसे कुंजी सेट करें। अन्यथा SQLite में एक रिकॉर्ड लगातार विभिन्न भूगोल के संस्करणों के साथ ओवरराइट होता रहेगा।
  • लंबे परिदृश्यों के लिए, पूरे कार्य के लिए एक ही देश और एक ही सत्र रखें। इसे कैसे करना है, इस पर विस्तार से स्टिकी सत्रों और उनका उपयोग कब करें पर चर्चा की गई है।
  • A/B परीक्षण और क्रमिक रोलआउट एक ही डोमेन पर दो जीवित लेआउट प्रदान करते हैं। यहां अनुकूलनीय खोज विशेष रूप से उपयोगी है: यह दोनों शाखाओं से तत्व को खींच लेगा, जबकि कठोर सेलेक्टर आधे अनुरोधों पर यादृच्छिक रूप से खाली देगा।

Scrapling में प्रॉक्सी को सभी स्तरों पर सेट किया जा सकता है। त्वरित HTTP अनुरोधों के लिए Fetcher और AsyncFetcher में proxies पैरामीटर है। सत्रों के लिए ProxyRotator है, जिसे पते की सूची दी जाती है - इसे FetcherSession में डाला जाता है। ब्राउज़र DynamicSession और StealthySession सत्र स्तर पर प्रॉक्सी स्वीकार करते हैं, ताकि आईपी स्क्रिप्ट के बीच में न बदले।

एक और चीज जो पूल और नसों को बचाती है, वह संस्करण 0.4.12 में आई - AutoThrottle: पुस्तकालय स्वचालित रूप से सर्वर के उत्तरों के अनुसार अनुरोधों के बीच विराम को समायोजित करता है, बैन होने पर विलंब को दोगुना करता है और Retry-After हेडर का सम्मान करता है। यह ठीक वही व्यवहार है जो सावधानीपूर्वक संग्रह को सरल रिट्राई के माध्यम से बैन के बढ़ने से अलग करता है।

छिपे हुए खतरे

  • SQLite के साथ फिंगरप्रिंट को git में कमिट न करें। इसके बारे में दस्तावेज़ीकरण में स्पष्ट रूप से चेतावनी दी गई है। साथ ही, व्यक्तिगत डेटा वाले पृष्ठों पर auto_save का उपयोग न करें - फिंगरप्रिंट में तत्व का पाठ और विशेषताएँ शामिल होती हैं।
  • अनुकूलनीय खोज निगरानी का विकल्प नहीं है। यह "सबसे समान" तत्व लौटाएगा, और सबसे समान हमेशा सही नहीं होता। यदि साइट ने छूट वाली कीमत और बिना छूट वाली कीमत को स्थानांतरित किया है, तो समानता उच्च है, लेकिन डेटा गलत है। मानों की सीमा और निकासी में खाली क्षेत्रों के अनुपात की जांच रखें।
  • चुप्पी से खराबी अधिक महंगी होती है। जब तक सेलेक्टर चुपचाप None लौटाता है, पाइपलाइन पृष्ठों पर चलती रहती है और भुगतान किए गए ट्रैफ़िक को जलाती है। वास्तव में एक गीगाबाइट की लागत क्या होती है, जिसमें से डेटा नहीं निकाला गया है, इस पर एक अलग विश्लेषण है - क्यों प्रॉक्सी की कीमत प्रति जीबी झूठी है.
  • फिंगरप्रिंट पुराना हो जाता है। पुष्टि किए गए रीडिज़ाइन के बाद मानक को फिर से लें, अन्यथा साइट का अगला संशोधन पुराने चित्र से माना जाएगा, और सटीकता गिर जाएगी।
  • यदि HTML में सामग्री बिल्कुल नहीं है - अनुकूलनीयता मदद नहीं करेगी, एक ब्राउज़र फेचर की आवश्यकता है। संस्करण 0.4.15 में ब्राउज़र टैब अनुरोधों के बीच पुन: उपयोग किए जाने लगे, और close_pages() विधि उन्हें मजबूरन बंद कर देती है; वहां हेडलेस मोड में फ्रीज को ठीक किया गया और Turnstile का समाधान ब्राउज़र की स्थानीयता पर निर्भर नहीं रहा।

इस प्रकार के प्रॉक्सी को इस कार्य के लिए क्या लेना चाहिए

चयन पार्सर द्वारा नहीं, बल्कि लक्षित साइट द्वारा निर्धारित किया जाता है:

  • डेटा सेंटर प्रॉक्सी - बिना गंभीर एंटी-बॉट के साइटों के लिए: दस्तावेज़ीकरण, सरकारी रजिस्टर, ओपन कैटलॉग, RSS और CSV फ़ीड (अंतिम के लिए 0.4.13 में XMLFeedSpider और CSVFeedSpider को gzip के स्वचालित अनपैकिंग के साथ जोड़ा गया)। सस्ता और तेज, और यहां मार्कअप की स्थिरता आमतौर पर अधिक होती है।
  • रेजिडेंशियल प्रॉक्सी - मार्केटप्लेस, एग्रीगेटर्स और जो कुछ भी भूगोल के अनुसार परिणाम को व्यक्तिगत बनाता है। यहीं मानक लेना और एक ही देश से डेटा एकत्र करना महत्वपूर्ण है, अन्यथा आप खराबी नहीं, बल्कि अपनी भूगोल को ठीक करेंगे।
  • मोबाइल प्रॉक्सी - जब साइट मोबाइल टेम्पलेट देती है और इसे वैसे ही पार्स करना आवश्यक होता है, या जब आईपी पर विश्वास जीबी की कीमत से अधिक महत्वपूर्ण होता है।

संक्षेप में

निकासी में खाली फ़ील्ड दो अलग-अलग निदान हैं जिनका अलग उपचार है। पहले उत्तर कोड और कच्चे HTML की जांच करें: यदि पृष्ठ पूरा आया है, तो प्रॉक्सी बदलने की आवश्यकता नहीं है, मार्कअप चला गया है। Scrapling के अनुकूलनीय सेलेक्टर्स इस प्रकार की खराबियों को अनुरोध पर कुछ मिलीसेकंड में बंद कर देते हैं - कार्यशील लेआउट पर फिंगरप्रिंट सहेजें, लड़ाई में adaptive=True चालू करें और ट्रिगर क्षणों को रीडिज़ाइन के संकेत के रूप में लॉग करें। और भूगोल को स्थिर रखें: आधे "अचानक रीडिज़ाइन" वास्तव में पृष्ठ के एक अन्य भाषा संस्करण के रूप में होते हैं, जो देश के परिवर्तन के कारण आया है।

यदि स्थिर भूगोल और पूर्वानुमानित सत्र आपके पार्सर की कमी है, तो ProxyCove के रेजिडेंशियल प्रॉक्सी पर विचार करें: देश का चयन, स्टिकी सत्र और वास्तव में उपयोग किए गए ट्रैफ़िक के लिए भुगतान।