أتمتة المتصفح باستخدام Puppeteer أو Playwright.

دقائق القراءة: 6

أتمتة المتصفح باستخدام Puppeteer أو Playwright

أتمتة المتصفح لم تعد مجرد أداة لاختبار الواجهات، بل أصبحت طبقة تشغيل حيوية في فرق التطوير، والتحليل، والدعم، وبناء الأنظمة الذكية. عندما نستخدم مكتبات مثل Puppeteer أو Playwright فنحن لا “نضغط أزراراً” فقط، بل نبني وكيل تنفيذ قادر على فتح الصفحات، تتبع عناصر DOM، التقاط الشبكة، ودمج النتائج مع خدمات خارجية.

هذه المقاربة مفيدة جداً عندما تكون البيانات أو الإجراءات غير متاحة عبر الـ API بشكل مباشر، أو عندما يكون المطلوب محاكاة سلوك المستخدم الحقيقي داخل لوحة تحكم، نظام تعليمي، أو بوابة داخلية. ولهذا ترتبط أتمتة المتصفح مباشرة بفكرة لماذا نحتاج الأتمتة؟ كيف توفر الشركات آلاف الساعات، لأن تقليل العمل اليدوي هنا ينعكس على السرعة والدقة والقدرة على التوسع.

متى نلجأ إلى أتمتة المتصفح بدلاً من التكامل المباشر؟

الأصل التقني دائماً هو استخدام REST API أو GraphQL عندما يكون ذلك متاحاً، كما أوضحنا في الفرق بين REST و SOAP و GraphQL: متى نختار كل نوع؟. لكن بعض المنصات لا توفر نقاط تكامل كافية، أو تفرض عمليات لا يمكن إجراؤها إلا عبر الواجهة الرسومية.

في هذه الحالات تصبح أتمتة المتصفح خياراً عملياً، خصوصاً في السيناريوهات التالية:

  • تسجيل الدخول إلى لوحة تحكم لا توفر Endpoint عاماً للمهام المطلوبة.
  • تعبئة نماذج دورات أو منصات تعليمية بشكل منظم وآمن.
  • استخراج تقارير مرئية أو ملفات CSV و PDF من صفحات ديناميكية.
  • اختبار تدفق المستخدم الكامل من واجهة الدخول حتى صفحة الدفع أو النشر.
  • مراقبة تغيّر العناصر أو الأسعار أو الحالات في صفحات ويب متجددة.

الفرق العملي بين Puppeteer و Playwright

Puppeteer طُوِّر أساساً للعمل بشكل ممتاز مع متصفح Chromium، وهو مناسب جداً إذا كانت احتياجاتك مركزة على الأتمتة السريعة، أخذ لقطات الشاشة، التنقل، أو جمع البيانات من تطبيقات مبنية على الويب. واجهته بسيطة، واعتماده واسع في مهام التشغيل اليومية.

أما Playwright فيقدّم طبقة أكثر تقدماً من حيث دعم المتصفحات المتعددة مثل Chromium و Firefox و WebKit، مع أدوات قوية لإدارة Context، العزل بين الجلسات، والانتظار الذكي للعناصر دون كتابة حلول التفافية كثيرة.

متى تختار كل أداة؟

  • اختر Puppeteer إذا كان المشروع خفيفاً، وسريع التنفيذ، ويركز على متصفح واحد.
  • اختر Playwright إذا كنت تريد اختبارات أكثر موثوقية، أو تحتاج دعماً متعدد المتصفحات والجلسات.
  • في بيئات التشغيل المؤسسية، يميل كثير من المهندسين إلى Playwright بسبب الاستقرار العالي في الانتظار التلقائي ومعالجة الحالات المتزامنة.

كيف تعمل أتمتة المتصفح من الداخل؟

السكربت لا يتعامل مع الصفحة كصورة، بل كبيئة تنفيذ كاملة. عند تشغيل المتصفح يقوم السكربت بإنشاء جلسة، فتح تبويب، تحميل الصفحة عبر بروتوكول HTTP، ثم انتظار اكتمال تحميل الموارد والطلبات غير المتزامنة. بعد ذلك يبدأ تحليل شجرة DOM والبحث عن العناصر عبر محددات مثل CSS Selector.

الأهم من ذلك أن أدوات الأتمتة تستطيع مراقبة الطلبات الصادرة إلى الخلفية. وهذا مفيد جداً إذا كنت تريد فهم بنية التطبيق أو التقاط بيانات من نداءات داخلية. ولمن يريد بناء فهم أعمق لطبيعة هذه النداءات، يفيد الرجوع إلى تشريح طلب الـ API: الـ Endpoint، الـ Headers، والـ Body، وكذلك لغة الـ JSON عند تحليل الاستجابات.

ملاحظة هندسية مهمة: كثير من مواقع الويب الحديثة تبني البيانات المعروضة في الواجهة من خلال طلبات XHR أو fetch. في بعض المشاريع، يكفي التقاط هذه الطلبات وإعادة استخدام بياناتها بدلاً من كشط العناصر المرئية، وهو أسلوب أكثر استقراراً وأسهل في الصيانة.

مثال عملي باستخدام Playwright

المثال التالي يوضح سيناريو شائعاً: فتح صفحة، انتظار عنصر تسجيل الدخول، تعبئة الحقول، ثم التقاط نص من لوحة التحكم. هذا النمط يمكن توسيعه لاحقاً لربطه مع أنظمة داخلية أو جدولة التشغيل عبر الجدولة الزمنية (CRON Jobs).

const { chromium } = require('playwright');

(async () => {
  const browser = await chromium.launch({ headless: true });
  const context = await browser.newContext();
  const page = await context.newPage();

  try {
    await page.goto('https://example.com/login', {
      waitUntil: 'domcontentloaded',
      timeout: 30000
    });

    await page.fill('#email', 'admin@example.com');
    await page.fill('#password', 'StrongPassword123');
    await page.click('button[type="submit"]');

    await page.waitForSelector('.dashboard-title', { timeout: 15000 });

    const title = await page.textContent('.dashboard-title');
    console.log({ status: 'success', title });

    await page.screenshot({ path: 'dashboard.png', fullPage: true });
  } catch (error) {
    console.error({
      status: 'error',
      message: error.message
    });
  } finally {
    await browser.close();
  }
})();

دمج أتمتة المتصفح مع APIs و Webhooks

القيمة الحقيقية تظهر عندما لا يبقى سكربت المتصفح معزولاً. يمكن مثلاً تشغيل الأتمتة بعد استقبال Webhook من نظام خارجي، أو بعد وصول طلب من خدمة وسيطة مثل Pipedream أو Make. وهنا يصبح المتصفح خطوة تنفيذ داخل خط سير أتمتة أكبر.

ومن المفيد أيضاً فهم الفرق بين استدعاء النظام لواجهة API وبين انتظار حدث خارجي عبر الفرق بين الـ API والـ Webhook. هذا الفهم يساعدك على اختيار نقطة الانطلاق الصحيحة للسكربت بدلاً من تشغيله عشوائياً أو على فترات غير مناسبة.

هيكلة موصى بها للتكامل:
1. استقبل حدثاً خارجياً عبر POST.
2. تحقق من الهوية أو التوقيع.
3. شغّل سكربت المتصفح كعامل تنفيذ.
4. خزّن النتيجة في قاعدة بيانات أو أرسلها إلى Endpoint داخلي.
5. أعد استجابة مختصرة تتضمن حالة التنفيذ أو رقم المهمة.

التعامل مع التوثيق، الجلسات، والحماية

أحد أكثر الأخطاء شيوعاً هو تخزين كلمات المرور أو المفاتيح السرية مباشرة داخل السكربت. الأفضل استخدام متغيرات البيئة وقراءة الأسرار من ملفات آمنة كما في كيفية تخزين المفاتيح السرية في ملفات .env. وإذا كان النظام يعتمد على جلسات أو رموز وصول، فافصل منطق المصادقة عن منطق التصفح قدر الإمكان.

بعض المنصات قد تستخدم Bearer Token أو تدفقات OAuth 2.0 في الخدمات المرافقة. لذلك يفيد الجمع بين أتمتة المتصفح ومعرفة مقدمة في OAuth 2.0 والتعامل مع الـ Bearer Tokens وتجديد الصلاحيات آلياً، خاصة إذا كانت العملية تتطلب إرسال نتائج لاحقاً إلى أنظمة خارجية.

أخطاء شائعة يجب توقعها

  • الاعتماد على محددات هشة تتغير مع أي تحديث في الواجهة.
  • عدم وضع مهلات Timeout واضحة للتحميل والانتظار.
  • إرسال عدد كبير من الطلبات أو الزيارات بسرعة تؤدي إلى الحظر، وهنا يظهر دور تحديد معدل الطلبات (Rate Limiting).
  • إهمال تحليل الاستجابات أو حالات الفشل مثل رموز الحالة HTTP Status Codes.
  • تشغيل الأتمتة على صفحات تعتمد على سياسات أمان أو اتصالات نطاقات متعددة دون فهم كافٍ لمشاكل CORS.

أفضل الممارسات لبناء سكربتات مستقرة وقابلة للصيانة

  1. استخدم طبقة إعدادات منفصلة لعناوين المواقع، بيانات الدخول، وأسماء العناصر.
  2. سجّل الأحداث المهمة مثل بداية المهمة، الصفحة الحالية، وسبب الفشل المحتمل.
  3. فضّل الالتقاط الشبكي أو البيانات البنيوية على القراءة البصرية متى أمكن.
  4. ابنِ وحدات مستقلة: تسجيل دخول، تنقل، استخراج بيانات، حفظ نتائج.
  5. اختبر السكربت على بيئة تجريبية قبل توجيهه إلى النظام الحي.

إذا كان هدفك هو بناء أتمتة مؤسسية طويلة الأجل، فلا تنظر إلى Puppeteer أو Playwright كأدوات نقر فقط، بل كطبقة تنفيذ ذكية تكمل ما لا تستطيع واجهات التكامل التقليدية تغطيته. وعند استخدامها ضمن هندسة مدروسة تشمل التوثيق، الحماية، المراقبة، والربط مع الأنظمة الأخرى، ستتحول أتمتة المتصفح من حل مؤقت إلى مكوّن إنتاجي موثوق يختصر الوقت ويرفع جودة التشغيل.

اترك تعليقاً

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *