كان جهاز التفسير يعمل لمدة ستة أشهر، واليوم تم إدخال سطور فارغة في قاعدة البيانات. الفكرة الأولى - تم حظره، يجب تغيير البروكسي. تقوم بتغيير المجموعة، وتحسين جودة IP، وتدفع مقابل السكن بدلاً من مراكز البيانات - ومع ذلك، تبقى الحقول فارغة. لأن السبب لم يكن في الحظر: انتقل الموقع إلى تصميم جديد، ولم يعد محدد CSS الخاص بك مرتبطًا بأي شيء.
هذا هو أغلى نوع من الأعطال، لأنه صامت. الحظر يظهر على الفور: 403، كابتشا، إعادة توجيه. انحراف التصميم لا يسقط شيئًا - HTTP 200، الصفحة تم الحصول عليها، حركة المرور مدفوعة، ولكن في النهاية None. دعونا نحلل كيف نميز بين الاثنين في خمس دقائق وكيف نتوقف عن إعادة كتابة المحددات يدويًا بعد كل إعادة تصميم.
لمن هذا مفيد
دليل لأولئك الذين يحتفظون بجهاز التفسير في الإنتاج لأكثر من سبرينت واحد: مراقبة أسعار المنافسين، جمع التعليقات، تجميع الوظائف، التحميل اليومي للتحليلات. إذا كنت تقوم بتشغيل البرنامج النصي مرة واحدة ثم تتخلص منه - فإن انحراف التصميم لا يهمك. إذا كان البرنامج النصي يعمل عبر cron لعدة أشهر، فهذا هو بند النفقات الرئيسي لديك للدعم.
حجم المشكلة ليس خياليًا. وفقًا لتقديرات محللي GroupBWT، فإن التغييرات الهيكلية غير المدارة في المواقع تؤدي إلى حوالي 40-60% من التكاليف المتكررة لدعم أجهزة التفسير في المشاريع الكبيرة. في بعض الصناعات، 10-15% من أجهزة الزحف تحتاج إلى إصلاح أسبوعيًا - بسبب تحولات DOM، وتحديد الهوية، وتقييد نقاط النهاية. بمعنى آخر، فإن إصلاح المحددات يتنافس من حيث التكلفة مع تجاوز مضاد الروبوتات، ولكن يتم تخصيص اهتمام أقل بكثير له.
الخلفية هنا ليست جيدة: في تقرير Apify "حالة الزحف على الويب 2026" 65.8% من المستجيبين زادوا من استخدام البروكسي، 58.3% أشاروا إلى زيادة النفقات على البروكسي من عام إلى عام، وأكثر من 62% - زيادة عامة في تكاليف البنية التحتية، بشكل رئيسي بسبب تعزيز الحماية من الروبوتات. في هذا السياق، من المؤلم مرتين حرق حركة المرور المدفوعة على صفحات لا تحصل منها على أي شيء.
الخطوة 1. تمييز الحظر عن انحراف التصميم
تستغرق التشخيصات بضع دقائق وتتم بدقة وفقًا للترتيب - وإلا فمن السهل "إصلاح" العطل الخطأ.
- انظر إلى رمز الاستجابة وحجم الجسم. 403، 429، 503، إعادة توجيه إلى صفحة التحقق أو جسم بحجم 2-5 كيلوبايت - هذا هو مضاد الروبوتات. HTTP 200 وصفحة كاملة بحجم 200-800 كيلوبايت - الموقع استقبلك، المشكلة ليست في البروكسي.
- احفظ HTML الخام على القرص وافتحه بعينيك. ليس في المصحح، ولكن في المتصفح. إذا كان المنتج/التعليق/السعر في مكانه، لكن جهاز التفسير لا يراه - فهذا هو انحراف التصميم.
- ابحث عن النص المطلوب باستخدام البحث في الملف. إذا كان موجودًا في HTML، لكنه غير متاح بمحددك - فقد تغيرت التنسيق. إذا لم يكن موجودًا على الإطلاق - يتم تحميل المحتوى بواسطة سكربت، تحتاج إلى محرك متصفح، وليس طلب HTTP.
- قارن مع التحميل الناجح السابق. قارن HTML القديم والجديد لنفس عنوان URL: عادة ما يكون من السهل رؤية الفئة الجديدة، أو الكتلة التي انتقلت، أو استبدال
idبـdata-*. - تحقق مما إذا كان الموقع قد أعطى إصدارًا آخر من الصفحة. حول هذا - منفصل أدناه، لأن البروكسي له علاقة بذلك.
إذا كانت التشخيص بعد النقطة الثالثة هي "التنسيق قد انحرف"، فإن تغيير البروكسي ليس له معنى. تحتاج إلى جهاز تفسير يمكنه العثور على العنصر، حتى عندما يتعفن المحدد.
الخطوة 2. ما هي المحددات التكيفية
الفكرة بسيطة: بدلاً من الارتباط بشكل صارم بالسطر .product-card > h3.title، تتذكر المكتبة "صورة" العنصر المطلوب مرة واحدة، وعند التشغيل التالي تبحث عن العنصر الأكثر تشابهًا مع هذه الصورة في الصفحة.
تم تنفيذ ذلك بشكل عملي في Scrapling - إطار عمل بايثون مفتوح المصدر من كريم شواهير. تم إصدار المشروع في أكتوبر 2024، وبحلول سبتمبر 2026، جمع أكثر من 78,000 نجمة على GitHub؛ الإصدار الأخير عند كتابة هذه السطور هو v0.4.15 من 23 أغسطس 2026، والتحديثات تتم يوميًا. يتطلب Python 3.10+.
تعمل آلية البحث التكيفي على النحو التالي. عندما تستدعي المحدد مع auto_save=True، يقوم Scrapling بحفظ بصمة العنصر:
- اسم العلامة، النص وجميع السمات مع قيمها؛
- أسماء علامات الجيران؛
- المسار إلى العنصر - فقط بأسماء العلامات؛
- العلامة، السمات والنص للوالد.
تُخزن البصمة في قاعدة بيانات محلية SQLite ويتم تأمينها بواسطة زوج "النطاق + المعرف". يتم أخذ النطاق من عنوان URL للصفحة (أو يتم تعيينه كمعامل adaptive_domain)، والمعرف الافتراضي هو نفس سلسلة المحدد - أو خاصتك إذا قمت بتمرير identifier=.
عندما يتغير التصميم ويعيد المحدد العادي فارغًا، فإن الاستدعاء مع adaptive=True يستعيد البصمة المحفوظة ويمررها عبر جميع عناصر الصفحة، محسوبًا تقييم التشابه الضبابي - حتى ترتيب السمات. يتم إرجاع العنصر الأكثر تطابقًا.
تكلفتها رخيصة. وفقًا لمعايير المشروع الرسمية، يستغرق التفسير 1.99 مللي ثانية مقابل 2.01 مللي ثانية لـ Parsel/Scrapy، 22.93 مللي ثانية لـ PyQuery، 80.57 مللي ثانية لـ Selectolax و1541 مللي ثانية لـ BeautifulSoup مع lxml. البحث التكيفي عن عنصر مشابه يستغرق 2.46 مللي ثانية مقابل 13.3 مللي ثانية لـ AutoScraper. بمعنى آخر، فإن التأمين ضد إعادة التصميم يضيف حوالي مللي ثانيتين إلى الطلب في ظل تأخير الشبكة الذي يصل إلى مئات المللي ثواني.
الخطوة 3. التثبيت والتشغيل
يعتمد التثبيت على ما إذا كنت بحاجة إلى متصفح:
pip install scrapling- فقط جهاز التفسير، بدون جزء الشبكة. يكفي إذا كنت تحصل على HTML باستخدام كودك.pip install "scrapling[fetchers]"، ثمscrapling install- يضيف الفيتشرز ويقوم بتنزيل المتصفحات مع التبعيات.- إضافي:
[ai]- خادم MCP،[rag]- تغليف لـ RAG،[shell]- وحدة تحكم تفاعلية،[all]- كل شيء دفعة واحدة. هناك صورة جاهزةpyd4vinci/scrapling.
بعد ذلك - هناك جولتان. الأولى على تصميم العمل الحي تحفظ البصمة، والثانية يمكنها البقاء بعد إعادة التصميم:
- جولة مرجعية. أنشئ كائن
Selectorمعadaptive=Trueوتأكد من تمريرurl- وإلا سيتجه النطاق إلى المفتاح"default"، وستختلط بصمات مواقع مختلفة. استدعِ المحدد المطلوب معauto_save=True. - جولة قتالية. نفس المحدد، ولكن مع
adaptive=True. طالما أن التنسيق سليم، ستعمل الطريقة العادية. عندما تتعطل - ستبدأ عملية البحث عن التشابه. - سجل الفروقات. اللحظة التي أعطى فيها المحدد العادي فارغًا، بينما وجد التكيفي شيئًا ما - هي إشارة "انتقل الموقع"، يجب رؤيتها في المراقبة، وليس ابتلاعها بصمت.
تفصيل مهم حول إعادة الكتابة: الحفظ لا يتراكم. سيؤدي auto_save المتكرر لنفس الزوج "النطاق + المعرف" إلى الكتابة فوق البصمة السابقة. لذلك يتم أخذ المرجع من صفحة صحيحة مسبقًا، وليس في حلقة عبر جميع مجموعة URL.
الخطوة 4. البروكسي: أين هي في الحقيقة
بدأنا بالقول إن انحراف التصميم ليس عن البروكسي. هذا صحيح تمامًا في نصفه، والنصف الآخر يكلف المال.
يمكن أن يعطيك الموقع تنسيقًا مختلفًا بسبب خروج البروكسي. المحلية، اللغة والبلد تغير نمط الصفحة: ترتيب مختلف للكتل، فئات مختلفة، تنسيقات مختلفة للأسعار والتواريخ. هذه ليست فرضية - في Scrapling نفسه هناك تصحيح مثير: في الإصدار 0.4.12 تمت إزالة المحلية القسرية en-US من StealthyFetcher، لأن المحلية المفروضة كانت تتعارض مع الجغرافيا الحقيقية وتكسر السلوك. ومن هنا القاعدة العملية: احفظ بصمة مرجعية من نفس الجغرافيا التي تجمع منها البيانات لاحقًا. ستكون البصمة المأخوذة عبر IP ألماني أقل تطابقًا مع الصفحة المستلمة عبر IP برازيلي - وستحصل على إنذار كاذب "تغير تصميم الموقع".
التبعات العملية:
- إذا كانت المجموعة متعددة البلدان - قم بتقسيم البصمات عبر
adaptive_domain، مع تعيين مفتاح مثل "النطاق + البلد". وإلا، ستتم الكتابة فوق سجل واحد في SQLite باستمرار بإصدارات من جغرافيا مختلفة. - للسيناريوهات الطويلة، احتفظ ببلد واحد وجلسة واحدة لكل المهمة. كيف يتم ذلك، تم شرحه بالتفصيل في المادة حول الجلسات الثابتة ومتى تستخدمها.
- اختبارات A/B والتوزيعات التدريجية تعطي في نفس الوقت تصميمين حيّين على نفس النطاق. هنا يكون البحث التكيفي مفيدًا بشكل خاص: سيستخرج العنصر من كلا الفرعين، بينما سيعطي المحدد الصارم فارغًا عشوائيًا في نصف الطلبات.
يمكن تعيين البروكسي في Scrapling على جميع المستويات. بالنسبة لطلبات HTTP السريعة، يحتوي Fetcher وAsyncFetcher على معامل proxies. للجلسات، يوجد ProxyRotator، الذي يتم تمرير قائمة العناوين إليه - يتم إدراجها في FetcherSession. تقبل الجلسات المتصفح DynamicSession وStealthySession البروكسي على مستوى الجلسة، حتى لا يتغير IP في منتصف السيناريو.
هناك شيء آخر يوفر المال والأعصاب، ظهر في الإصدار 0.4.12 - AutoThrottle: تقوم المكتبة بضبط الفواصل الزمنية بين الطلبات بناءً على استجابات الخادم، تضاعف التأخير عند الحظر وتحترم رأس Retry-After. هذا هو السلوك الذي يميز الجمع الدقيق عن تسريع الحظر بواسطة إعادة المحاولات الساذجة.
الألغام تحت الماء
- لا تقم بإدخال SQLite مع البصمات في git. تحذر الوثائق من ذلك بشكل مباشر. بالإضافة إلى ذلك، لا تستخدم
auto_saveعلى الصفحات التي تحتوي على بيانات شخصية - حيث يتم تضمين النص والسمات في البصمة. - البحث التكيفي ليس بديلاً عن المراقبة. سيعيد "العنصر الأكثر تشابهًا"، لكن الأكثر تشابهًا ليس دائمًا صحيحًا. إذا قام الموقع بتبديل السعر المخفض والسعر الكامل، فإن التشابه سيكون مرتفعًا، والبيانات غير صحيحة. احتفظ بالتحقق من نطاق القيم ونسبة الحقول الفارغة في التحميل.
- العطل الصامت أغلى من العطل الصاخب. بينما يقوم المحدد بإرجاع None بصمت، يستمر خط الأنابيب في المرور عبر الصفحات وحرق حركة المرور المدفوعة. حول ما يكلف فعليًا غيغابايت لم يتم استخراج البيانات منها، هناك تحليل منفصل - لماذا سعر البروكسي لكل غيغابايت مضلل.
- تتقدم البصمة في العمر. بعد إعادة التصميم المؤكدة، قم بإعادة أخذ المرجع مرة أخرى، وإلا ستعتبر التعديلات التالية على الموقع من صورة قديمة، وستنخفض الدقة.
- إذا لم يكن هناك محتوى في HTML على الإطلاق - فإن التكيف لن يساعد، تحتاج إلى جهاز تفسير متصفح. في 0.4.15، بدأت علامات التبويب في المتصفح تُستخدم مرة أخرى بين الطلبات، وطريقة
close_pages()تغلقها قسريًا؛ كما تم إصلاح التوقفات في وضع headless وأصبح حل Turnstile غير معتمد على المحلية للمتصفح.
ما هو نوع البروكسي الذي يجب استخدامه لهذه المهمة
يتم تحديد الاختيار ليس من قبل جهاز التفسير، ولكن من قبل الموقع المستهدف:
- بروكسي مراكز البيانات - للمواقع التي لا تحتوي على مضاد روبوتات قوي: الوثائق، السجلات الحكومية، الأدلة المفتوحة، خلاصات RSS وCSV (لآخرها، تمت إضافة
XMLFeedSpiderوCSVFeedSpiderمع فك ضغط gzip تلقائيًا في 0.4.13). رخيصة وسريعة، وعادة ما تكون استقرار التنسيق هنا أعلى. - بروكسي سكنية - للأسواق، المجمعات وكل ما يقوم بتخصيص النتائج حسب الجغرافيا. هنا من الضروري أخذ البصمة المرجعية وجمع البيانات من بلد واحد، وإلا ستقوم بإصلاح ليس عطلًا، بل جغرافيا خاصة بك.
- بروكسي موبايل - عندما يعطي الموقع نموذجًا مخصصًا للجوال ويجب تفسيره كما هو، أو عندما تكون الثقة في IP أكثر أهمية من السعر لكل غيغابايت.
باختصار
الحقول الفارغة في التحميل هي تشخيصان مختلفان مع علاج مختلف. أولاً تحقق من رمز الاستجابة وHTML الخام: إذا جاءت الصفحة كاملة، فلا حاجة لتغيير البروكسي، بل انحرف التنسيق. تحدد المحددات التكيفية في Scrapling هذا النوع من الأعطال في غضون مللي ثوانٍ - احفظ البصمة على التصميم العامل، قم بتشغيل adaptive=True في المعركة وسجل لحظات التشغيل كإشارة لإعادة التصميم. واحتفظ بالجغرافيا مستقرة: نصف "إعادة التصميم المفاجئة" في الواقع يتبين أنها إصدار لغة مختلف من الصفحة، جاء بسبب تغيير بلد الخروج.
إذا كانت الجغرافيا المستقرة والجلسة المتوقعة هي ما ينقص جهاز التفسير الخاص بك، انظر إلى البروكسي السكنية من ProxyCove: اختيار البلد، جلسات لزجة والدفع مقابل حركة المرور المستخدمة فعليًا.
