انتقل إلى المحتوى

كيفية التقاط لقطات الشاشة باستخدام محرك الدمى لتخريب الويب بشكل فعال

Puppeteer هي مكتبة Node.js توفر واجهة برمجة تطبيقات قوية للتحكم في Chrome وChromium بدون رأس عبر بروتوكول DevTools. إحدى ميزاته الأكثر فائدة هي القدرة على التقاط لقطات شاشة لصفحات الويب والعناصر برمجيًا.

بالنسبة إلى أدوات استخراج بيانات الويب، فإن القدرة على التقاط لقطات شاشة باستخدام Puppeteer تفتح مجموعة متنوعة من حالات الاستخدام القيمة:

  • تصحيح الأخطاء بصريًا لمشكلات الكشط وفشل الاختبار.
  • التقاط حالات الصفحات الديناميكية والمنتجعات الصحية.
  • مراقبة الانحدارات المرئية وتغييرات واجهة المستخدم.
  • إنشاء برامج تعليمية ووثائق مع لقطات شاشة للسياق.
  • توليد أصول الصور من صفحات الويب.

في هذا الدليل الشامل، سنستكشف كيفية الاستفادة من لقطات شاشة Puppeteer لتحسين سير عمل تجريف الويب لديك.

صعود محرك الدمى لكشط الويب

تم إصدار Puppeteer لأول مرة في عام 2017 وشهد اعتمادًا سريعًا من قبل مجتمع تجريف الويب. فيما يلي بعض الإحصائيات التي تسلط الضوء على شعبيتها:

  • أكثر من 52,000 نجم على Github مما يجعله واحدًا من أفضل مشاريع JS.
  • أكثر من 3 ملايين عملية تنزيل أسبوعية على NPM.
  • نمو بنسبة 490% على أساس سنوي في عمليات البحث على Google عن Puppeteer في عام 2022.

إذن ما الذي يميز Puppeteer عن تجريف الويب؟

التحكم في المتصفح بدون رأس

يوفر Puppeteer تحكمًا كاملاً في المتصفح بدون رأس عبر بروتوكول Chrome DevTools. يتيح ذلك تكرار تفاعلات المستخدم من أجل التشغيل الآلي واستخراج المحتوى الديناميكي.

خفيف الوزن وسريع

كونك بدون رأس فقط يعني أن محرك الدمى يتخطى جميع عروض واجهة المستخدم التي تجعل من Chromium ثقيل الوزن. وهذا يؤدي إلى أداء سريع للتجريف على نطاق واسع.

التنمية النشطة

بدعم من فريق Chrome في Google، يحصل Puppeteer على تحديثات متكررة وميزات جديدة مصممة خصيصًا للتشغيل الآلي واستخراج حالات الاستخدام.

أبسط من السيلينيوم

يركز Puppeteer فقط على التحكم في Chromium بينما يدعم Selenium متصفحات متعددة. واجهة برمجة التطبيقات (API) أكثر نظافة واصطلاحية مما يجعلها سهلة الاستخدام.

لهذه الأسباب، تتحول العديد من برامج كاشطات الويب إلى Puppeteer من Selenium/WebDriver لتحسين السرعة والموثوقية والقدرة.

الآن دعونا نتعمق في كيفية الاستفادة من إمكانيات لقطة الشاشة القوية في Puppeteer.

التقاط لقطات شاشة كاملة للصفحة

أسهل طريقة لالتقاط لقطة شاشة لصفحة بأكملها هي استخدام page.screenshot() الأسلوب:

// Launch browser
const browser = await puppeteer.launch();

// Open page 
const page = await browser.newPage();
await page.goto(‘https://example.com‘);

// Screenshot
await page.screenshot({
  path: ‘fullpage.png‘ 
});

يؤدي هذا إلى التقاط إطار العرض المرئي حاليًا. لالتقاط لقطة شاشة لارتفاع الصفحة بالكامل، قم بتعيين fullPage الخيار ل true:

await page.screenshot({
  path: ‘longpage.png‘,
  fullPage: true
}); 

تحديد خيارات الصورة

screenshot() تقبل الطريقة خيارات للتحكم في النوع والجودة والمزيد:

  • type - png أو jpeg أو webp. الافتراضي هو بابوا نيو غينيا.
  • quality - بالنسبة لملفات jpeg/webp، تتراوح الجودة من 0 إلى 100. الافتراضي هو 80.
  • omitBackground - يخفي الخلفية البيضاء الافتراضية ويسمح بالشفافية.
  • encoding - يمكن الإخراج كـ base64 بدلاً من حفظ الملف.

على سبيل المثال، لحفظ ملف jpeg عالي الجودة:

await page.screenshot({
  path: ‘page.jpeg‘,
  type: ‘jpeg‘,
  quality: 100
});

معلومه- سرية: استخدم webp لضغط أفضل وبجودة مكافئة. ومع ذلك، قد يواجه webp مشكلات في التوافق.

التعامل مع لقطات الشاشة الكبيرة

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

للتعامل مع لقطات الشاشة الكبيرة، قم بتمرير الخيار encoding: ‘base64‘ للحصول على سلسلة base64 بدلاً من المخزن المؤقت. ثم احفظ باستخدام fs.writeFile() لتجنب تخزين الصورة مؤقتًا في الذاكرة.

هنا مثال:

const buffer = await page.screenshot({ encoding: ‘base64‘ });

fs.writeFile(‘screenshot.png‘, buffer, ‘base64‘, err => {
  // handle error 
});

تمرير الصفحات الطويلة لالتقاط صفحة كاملة

لالتقاط الارتفاع الكامل للصفحات الأطول من إطار العرض، سنحتاج إلى تمرير الصفحة أولاً.

إليك طريقة واحدة تستخدم page.evaluate():

// Scroll to bottom  
await page.evaluate(() => {
  window.scrollTo(0, document.body.scrollHeight);
});

// Screenshot full scrollable area
await page.screenshot({ path: ‘longpage.png‘, fullPage: true });

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

البديل: حفظ بصيغة PDF

خيار آخر لالتقاط محتوى الصفحة بالكامل – إنشاء ملف PDF!

// Generates PDF and saves to disk 
await page.pdf({
  path: ‘page.pdf‘,
  printBackground: true
});

إيجابيات ملفات PDF:

  • يتعامل مع محتوى متعدد الصفحات خارج الصندوق.
  • عادةً ما ينتج عن التنسيق المتجه أحجام ملفات أصغر.
  • يبقى تنسيق الطباعة سليمًا.

سلبيات:

  • أقل مرونة للمعالجة البرمجية.
  • خيارات تصميم محدودة مقارنة بالصور.
  • قد لا يلتقط المحتوى المعروض ديناميكيًا.

تحديد حجم إطار العرض

افتراضيًا، يستخدم محرك الدمى إطار عرض بحجم 800 بكسل × 600 بكسل. للحصول على لقطات شاشة دقيقة لكامل الصفحة على أحجام مختلفة لسطح المكتب والهاتف المحمول، يمكننا ضبط إطار العرض بشكل صريح:

// 1200px wide desktop 
await page.setViewport({
  width: 1200,
  height: 800  
});

// 400px wide mobile
await page.setViewport({
  width: 400,
  height: 1200 
});

ثم ستتطابق لقطات الشاشة مع حجم إطار العرض المحدد.

التقاط العناصر

بالإضافة إلى لقطات الشاشة الكاملة للصفحة، يمكننا التقاط لقطات شاشة لعناصر محددة باستخدام element.screenshot().

// Get reference to element
const menu = await page.$(‘.main-menu‘);

// Screenshot just that element
await menu.screenshot({path: ‘menu.png‘});

سيتم تمرير العنصر إلى العرض قبل التقاط لقطة الشاشة. يتيح ذلك التقاط لقطات للعناصر التي قد تكون خارج الشاشة دون الحاجة إلى التمرير إليها.

بعض حالات الاستخدام لقطات الشاشة للعناصر:

  • التقاط لقطات شاشة للمكونات الديناميكية مثل المؤشرات أو الرسوم المتحركة.
  • تصحيح مشكلات التخطيط عن طريق التقاط لقطات للعناصر الفردية.
  • الحصول على أصول الصور من الرموز والرسوم التوضيحية.

لقطات شاشة للعنصر خارج الشاشة

إحدى المشكلات الشائعة هي حجب العناصر أو نقلها عند محاولة التقاط لقطات شاشة أثناء التفاعلات.

يمكننا الاستفادة من التمرير التلقائي للعنصر element.screenshot() لالتقاط العناصر بشكل موثوق في أي حالة، حتى عندما تكون خارج الشاشة:

// Click button which hides the element 
await page.click(‘.toggle-menu‘);

// Menu is now hidden but we can still screenshot it
await menu.screenshot({path: ‘hidden-menu.png‘}); 

يتيح ذلك التقاط لقطة شاشة بسهولة دون إعادة تعيين حالة الصفحة.

في انتظار تحميل المحتوى الديناميكي

عند العمل مع الصفحات الديناميكية، سنحتاج إلى انتظار عرض المحتوى قبل التقاط لقطات الشاشة لالتقاط الحالة المطلوبة.

فيما يلي مثال في انتظار ظهور عنصر:

// Click button to trigger ajax call
await page.click(‘.load-content‘);

// Wait for new content to load
await page.waitForSelector(‘.loaded‘);

// Screenshot after loaded
await page.screenshot({path: ‘loaded.png‘}); 

page.waitForSelector() ينتظر حتى يكون المحدد موجودًا في DOM قبل المتابعة.

تتضمن بعض فترات الانتظار المفيدة الأخرى ما يلي:

  • page.waitFor() - انتظر حتى يصبح الشرط معينًا صحيحًا.
  • page.waitForFunction() – انتظر حتى تكتمل تحديثات DOM غير المتزامنة.
  • page.waitUntil() - انتظر حتى يحدث التنقل.

المفتاح هو اختيار حالة الانتظار الصحيحة لتحديث الصفحة الذي تريد التقاطه في لقطة شاشة.

في انتظار تغييرات DOM محددة

للمزامنة مع المزيد من تغييرات DOM المنفصلة، ​​يمكننا الانتظار حتى يتم تحديث السمات بدلاً من المحددات الشاملة:

// Wait for text content to change
await page.waitForFunction(() => {
  return document.querySelector(‘.status‘).textContent === ‘Loaded‘; 
});

// Element updated  
await page.screenshot({/*...*/});

يعمل هذا الأسلوب بشكل جيد لانتظار تحميل البيانات الأساسية بدلاً من تغييرات DOM الثابتة.

التعامل مع تطبيقات الصفحة الواحدة (SPA)

يمكن أن يكون انتظار تغييرات DOM أمرًا صعبًا مع منتجعات JavaScript SPA المعقدة التي تعمل على تحديث الحالة دون إعادة التحميل.

بعض النصائح للتعامل مع هذه:

  • انتظر حتى تكون الشبكة خاملة بعد التفاعلات للسماح بإكمال XHRs.
  • انتظر حتى تختفي مكونات محددة مثل التراكبات بدلاً من المحددات الشاملة.
  • قم بالتمرير إلى القسم المطلوب لفرض العرض قبل التقاط لقطة الشاشة.
  • استخدم فترات الانتظار المتزايدة بدلاً من المهلات الثابتة.

لا يوجد نهج واحد يعمل بشكل مثالي لجميع المنتجعات الصحية. سيكون عليك تجربة التطبيق المعني.

تمرير الصفحات قبل التقاط لقطات شاشة كاملة للصفحة

بالنسبة للصفحات التي تتطلب التمرير، سنحتاج إلى التمرير برمجيًا قبل التقاط لقطة شاشة كاملة fullPage: true.

وإليك نهج موثوق:

await page.evaluate(() => {
  // Scroll to bottom
  window.scrollTo(0, document.body.scrollHeight);
}); 

// Capture full scrolled screenshot  
await page.screenshot({fullPage: true});

يؤدي هذا إلى تمرير الصفحة لأسفل إلى أقصى موضع للتمرير قبل التقاط لقطة الشاشة.

البديل يستخدم window.scrollBy() للتمرير بشكل متزايد بمقدار معين في كل مرة. يتيح ذلك التقاط لقطات شاشة متواصلة أثناء التمرير لأسفل بطول الصفحة بالكامل.

التعامل مع الصفحات الطويلة القابلة للتمرير

بالنسبة للصفحات الطويلة للغاية، قد يظل تمرير الطول بالكامل دفعة واحدة يتجاوز حدود الذاكرة أو الوقت.

الحل الجيد هو تقسيمها إلى أقسام، والتمرير قليلاً في كل مرة، والتقاط لقطات الشاشة، ودمجها معًا:

const screenshots = [];

while (hasMoreContent()) {

  await page.evaluate(scrollDown);

  screenshots.push(await page.screenshot()); 

}

// Stitch screenshots together into one tall image

وهذا يمنع الاضطرار إلى تخزين ارتفاع الصفحة بالكامل مؤقتًا في الذاكرة.

التمرير أفقيًا أيضًا

بالنسبة للصفحات ذات التمرير الأفقي، يمكننا ضبط تسلسل التمرير للتمرير أفقيًا أيضًا:

await page.evaluate(() => {
  window.scrollTo(
    document.body.scrollWidth, 
    document.body.scrollHeight
  );
});

await page.screenshot({fullPage: true});

هذا يلتقط عرض الصفحة بالكامل وارتفاعها!

أفضل الممارسات للحصول على لقطات شاشة موثوقة

فيما يلي بعض النصائح الأساسية لالتقاط لقطات شاشة متسقة وموثوقة باستخدام Puppeteer:

انتظر حتى تكون الشبكة خاملة - استعمال page.waitForNetworkIdle() بعد التفاعلات لضمان اكتمال جميع طلبات المزامنة قبل التقاط الحالة.

استخدم فترات الانتظار المناسبة – اختر فترات انتظار مشروطة تتزامن مع حالة الصفحة المطلوبة بدلاً من المهلات الشاملة.

ضبط حجم إطار العرض - قم بتعيين إطار العرض بشكل صريح لالتقاط لقطات شاشة دقيقة للجهاز.

درع من الرسوم المتحركة / النوافذ المنبثقة - يمكن للعناصر المتحركة أن تؤدي إلى تغييرات - الاستخدام page.evaluate() لتجنب الآثار الجانبية.

إتاحة الوقت للتقديم – انتظر بضع مئات من المللي ثانية بعد التمرير حتى انتهاء عرض الصفحات قبل لقطات الشاشة.

تحقيق الاستقرار في الاختبارات غير المستقرة - قم بتعيين حلقة إعادة المحاولة مع الانتظار حول خطوات لقطة الشاشة للتعامل مع الرقائق.

قارن مع الخير المعروف – الاستفادة من أدوات اختبار الانحدار البصري لاكتشاف التغييرات غير المقصودة.

وفي الختام

آمل أن يقدم هذا الدليل نظرة عامة شاملة حول التقاط لقطات شاشة كاملة للصفحة والعناصر باستخدام Puppeteer لتلبية احتياجاتك في تجريف الويب.

بعض المواضيع الرئيسية التي تناولناها:

  • استخدام page.screenshot() و element.screenshot() لالتقاط لقطات الشاشة
  • خيارات للتحكم في نوع الصورة وجودتها وتنسيقها
  • تمرير الصفحات وانتظار المحتوى الديناميكي
  • تحديد حجم إطار العرض للصفحات سريعة الاستجابة
  • أفضل الممارسات لسير عمل لقطات الشاشة الموثوقة

تعتبر لقطات الشاشة التلقائية لا تقدر بثمن لتصحيح أخطاء الكاشطات والاختبار المرئي والتقاط الحالات الديناميكية. قم بإضافتها إلى مجموعة أدوات تجريف الويب الخاصة بك باستخدام محرك الدمى!

الوسوم (تاج):

الانضمام إلى محادثة

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