بناء متتبع أسعار Amazon في Python (الطريقة الصحيحة)
بناء متتبع أسعار عملي باستخدام Python و Selenium، مع اختبارات حقيقية لما يحجبك فعلاً
النقاط الرئيسية
- صفحات المنتجات نادراً ما تحجب أدوات الكشط؛ في الاختبارات، مرّت 150 طلباً دون حجب واحد.
- تحجب صفحات بحث Amazon عند أول طلب، حتى مع استخدام بروكسي.
- الحجب مرتبط بعدم كونك متصفحاً حقيقياً، أكثر من ارتباطه بعنوان IP الخاص بك.
- يلزم بروكسي موجَّه لدولة بعينها للحصول على التسعير المحلي الصحيح، وليس فقط لتجنب الحجب.
ظننت أنني وجدت أرخص PlayStation 5 على الإنترنت.
طبع متتبعي السعر $74.00 بجانب PS5، لكن إذا بدا الأمر جيداً جداً لكي يكون حقيقياً على الإنترنت، فهو في الغالب كذلك. لم تكن تلك الـ $74 ثمنَ الجهاز. كانت أداة الكشط تختار العنصر الخاطئ، وهذا هو النوع بالضبط من الأخطاء الصامتة التي تجعل معظم دروس «متتبع أسعار Amazon» عديمة الفائدة في صمت.
لذا بدلاً من مجرد نشر خمسين سطراً من Python والانتهاء، وهو ما يفعله كل دليل تقريباً، اختبرت الأمر بشكل صحيح. شغّلته على Amazon بكثافة، وقست بالضبط ما يُحجَب وما لا يُحجَب، وأصلحت الأخطاء التي لا يذكرها أي دليل. كانت النتائج مفاجئة حقاً: أداة كشط مجردة ضربت صفحة منتج 150 مرة دون أن تُحجَب مرة واحدة، لكنها أُوقفت عند أول طلب لصفحة بحث.
هذا الدليل يحتوي على المتتبع الذي يعمل فعلاً، إضافةً إلى كل ما كشفت عنه الاختبارات، بما في ذلك حيلة في Selenium تستحق المعرفة حتى لو سبق لك بناء أدوات كشط: إذ تقود نافذة Chrome حقيقية بصرياً، فتشاهد تحميل الصفحة والكشط في الوقت الفعلي.
هل ستحجبك Amazon فعلاً؟
كل دليل يحذرك من أن Amazon ستحجب أداة الكشط لديك فوراً. لذا اختبرت الأمر، والنتائج أرباكتني حقاً.
وجّهت أداة كشط بسيطة خالية من أي إضافات إلى صفحة منتج PlayStation 5 وتركتها تُرسل الطلبات بلا توقف. طلب واحد، اثنان، عشرة، خمسون — كنت أنتظر الحائط. لم يأتِ أبداً. أرسلت 150 طلباً إلى نفس الصفحة وعاد كل واحد منها بـ «ok». لم أستطع تصديق مدى انفتاحها.
وكانت كذلك فعلاً. صفحات المنتجات، كما تبيّن، بالكاد تهتم. ثم وجّهت نفس أداة الكشط إلى صفحة نتائج البحث، فأُوقفت عند أول طلب. ليس العاشر، ولا الخمسين. الأول. 503 على الفور.
نتائج البحث هي المكان الذي يحدث فيه حصاد البيانات الحقيقي، فلذلك تُركّز Amazon دفاعاتها هناك. صفحات المنتجات الفردية؟ مفتوحة على مصراعيها.
إليك ما جربته وما حدث:
صفحة المنتج، أداة كشط مجردة: 150 طلب، صفر حجب
صفحة البحث، أداة كشط مجردة: محجوبة عند الطلب رقم 1 (503)
صفحة البحث، ترويسات أفضل: لا تزال محجوبة عند الطلب رقم 1
صفحة البحث، ترويسات + بروكسي سكني: لا تزال محجوبة عند الطلب رقم 1
صفحة البحث، متصفح حقيقي: نجحت، 16 نتيجة
صفحة البحث، متصفح + بروكسي أمريكي: نجحت، 22 نتيجة
الجزء الذي فاجأني أكثر: إضافة بروكسي سكني لصفحة البحث لم تُجدِ شيئاً على الإطلاق. لا تزال محجوبة، عند أول طلب. لم يكن الحجب يوماً بسبب عنوان IP الخاص بي، بل بسبب أنني لم أكن متصفحاً حقيقياً. في اللحظة التي حمّلت فيها نفس صفحة البحث في متصفح فعلي بدلاً من سكريبت خام، نجح الأمر:
بناء المتتبع
لنبنِ الأمر. المتتبع بأكمله نحو 50 سطراً من Python. تحتاج إلى Python 3 و Google Chrome مثبّتَين، ثم أمر واحد لتثبيت المكتبات:
pip install selenium requests matplotlib
توجيهه نحو منتج
لكل منتج على Amazon معرّف يُسمى ASIN، وهو رمز من 10 أحرف في URL يأتي مباشرةً بعد /dp/. على سبيل المثال، في amazon.com/dp/B0F1J12R6N، الـ ASIN هو B0F1J12R6N. هذا كل ما يحتاجه المتتبع للعثور على منتج.
لماذا requests وحدها لا تكفي
الطريقة الأوضح للكشط عن صفحة هي مكتبة requests في Python: سطر واحد، احصل على HTML، انتهى الأمر. وبالنسبة لصفحة منتج، فهي تُرجع حتى 200 OK. لكن إليك الفخ الذي وقعت فيه: الـ 200 لا تعني أنك حصلت على البيانات. Amazon تبني السعر في الصفحة باستخدام JavaScript، و requests لا تُشغّل JavaScript. فتحصل على الصفحة، لكن السعر ليس فيها.
لهذا يستخدم هذا المتتبع Selenium عوضاً عن ذلك. يقود Selenium متصفح Chrome حقيقياً: يفتح الصفحة فعلاً، ويُشغّل JavaScript، ويتيح لك قراءة النتيجة المعروضة بالكامل. في المرة الأولى التي تشغّله فيها، يفتح Chrome من تلقاء نفسه مع شريط يقول «يتم التحكم في Chrome بواسطة برنامج اختبار مؤتمت»، وتشاهده يعمل في الوقت الفعلي.
الكشط عن السعر (والخطأ الذي يرسله الجميع)
هنا تنكسر معظم الدروس في صمت. النهج الشائع يستهدف عنصر .a-price ويقرأ نصه. المشكلة: Amazon تضع السعر في ذلك العنصر مرتين، مرة مرئية ومرة لقارئات الشاشة، فتحصل على $449.00$449.00 مشوّهاً بدلاً من رقم نظيف.
الحل هو استهداف النسخة النظيفة والوحيدة من السعر داخل صندوق الشراء وقراءتها بعناية، مع التحقق من سعر صندوق الشراء الرئيسي أولاً حتى لا تلتقط عن طريق الخطأ سعر إكسسوار، وهو بالضبط ما أوصلني إلى تلك «PS5 بـ $74». المحددات الدقيقة موجودة في الكود على GitHub.
بمجرد استهداف العنصر الصحيح، يعود السعر نظيفاً:
تخزين السجل ورسم المخطط البياني
متتبع السعر لا يكون مفيداً إلا إذا تذكّر. يحفظ السكريبت كل قراءة إلى ملف مفهرس حسب المنتج، مخزّناً السعر كرقم فعلي مع عملته، لا كسلسلة نصية «$54.00». هذا مهم: الأرقام يمكنك رسمها بيانياً ومقارنتها وإيجاد أدناها؛ السلاسل النصية لا يمكنك. إذا تُرك وحده، يتحقق السكريبت مرة واحدة ثم يتوقف؛ أضف خيار حلقة وسيعيد التحقق وفق جدول زمني، فيبني سجلاً بمرور الوقت يحوّله سكريبت صغير ثانٍ إلى مخطط السعر عبر الزمن.
الخطأ الذي كاد يكلفني: قد تكون تكشط عن الدولة الخاطئة
تتذكر PlayStation بـ $74؟ كانت تلك العلامة الأولى على أن شيئاً ما خاطئ. الثانية كانت أسوأ، لأنها كانت أصعب في الاكتشاف.
حين شغّلت المتتبع لأول مرة بدون بروكسي، لم تعطني Amazon أسعاراً غريبة فحسب — بل أعطتني لبعض المنتجات لا سعرَ حقيقياً على الإطلاق، فقط إشعار «لا يمكن شحن هذا المنتج إلى موقعك». لم يكن لدى المتتبع شيء مفيد يُسجّله.
لذا وجّهته عبر بروكسي ليبدو كمتسوق أمريكي. عاد السعر باليورو. في البداية ظننت أن البروكسي لم يعمل أصلاً. ثم لاحظت أن الصفحة تقول «التسليم إلى أيرلندا»، فانقدح في ذهني: البروكسي عمل بشكل جيد، لكنه وضعني على عنوان IP أيرلندي. الفكرة صحيحة، الدولة خاطئة.
الحل هو بروكسي سكني مثبّت على الدولة التي تهتم بها فعلاً. بمجرد أن ثبّتُه على الولايات المتحدة، جلب المتتبع السعر الصحيح، $54.00، بالدولار، في كل مرة.
وتثبيت الدولة هذا ليس ميزةً اختيارية — إنه صميم الهدف. لنقل إنك تتابع أسعار المنافسين لتقرر ما تفرضه في سوق معين. تلك الأرقام لا تعني شيئاً إلا إذا كانت الأسعار التي يراها ذلك السوق فعلاً. المنتج نفسه قد يكون بـ $449 في الولايات المتحدة و €499 في أيرلندا. إذا أعادك كاشطك بصمت السعرَ الأيرلندي، فأنت تتخذ قرارات لسوق واحد بناءً على بيانات سوق آخر، وبما أن الأمر يبدو صحيحاً، لا أحد يلتقط الخطأ.
إذن البروكسي هنا ليس للتحايل على الحجب — اختباراتي أظهرت أن صفحات المنتجات بالكاد تحجب على أي حال. إنه للتأكد من أن البيانات التي تجمعها هي البيانات الصحيحة.
إذا كنت تريد بيانات أسعار مثبّتة على دولة محددة، فإن البروكسيات السكنية من FlashProxy تتيح لك استهداف أي موقع، فتجمع دائماً الأسعار التي يراها ذلك السوق فعلاً.
إذن… هل كان يجب أن يكون هذا أصعب؟
إليك انطباعي الصادق: إذا احتجت يوماً إلى كشط الأسعار من صفحة ويب، فلست مضطراً إلى قراءة مئات المدونات، أو مشاهدة ركام من مقاطع YouTube، أو مواصلة إلحاح الذكاء الاصطناعي حتى يُصيب أخيراً. يمكنك ببساطة أن تفعل ذلك بنفسك. الأمر سهل للغاية، وبصراحة، يكاد يكون مقلقاً هذا المستوى من السهولة.
قبل أن أبدأ، ظننت أن هذا سيكون صعباً. كنت متوتراً حقاً حين شغّلت الاختبارات الأولى بدون بروكسي متصل، إذ ظننت أنني سأُحجَب إلى الأبد، أو أن معدل الطلبات سيُقيَّد بشكل مجنون. كنت أتوقع عواقب.
لم يحدث شيء. حرفياً، لا شيء. 150 طلباً على صفحة منتج، بدون بروكسي، بدون حجب، بدون حظر، بدون بريد إلكتروني غاضب. الحائط الذي كنت أستعد له لم يكن موجوداً في معظمه، والمكان الوحيد الذي كان فيه (صفحات البحث)، اخترقه متصفح حقيقي بكل سهولة.
لذا إذا كان الشيء الوحيد الذي يمنعك من بناء أحد هذه الأدوات هو ظنك أن الأمر صعب أو محفوف بالمخاطر: فهو ليس كذلك. ابنه. فقط أبقِه معقولاً، تتبع الأسعار العامة، لا تُثقل الموقع بالطلبات، واحترم شروط الاستخدام. أما الخوف؟ فهو في معظمه في رأسك، تماماً كما كان في رأسي.
الكود الكامل
المشروع الكامل — المتتبع، ومساعد البروكسي، والرسم البياني، وسكريبتات الاختبار — مفتوح المصدر: amazon-price-tracker-python على GitHub. استنسخه وشغّله، أو اقرأ بالضبط كيف يعمل.


