هل تحاول الاختيار بين محرك الدمى والسيلينيوم لتجريد الويب؟ كلاهما إطاران قويان لأتمتة المتصفح، ويعتمد الاختيار الصحيح على احتياجاتك المحددة والموارد المتاحة.
لمساعدتك على اتخاذ قرار مستنير، قمنا بتسليط الضوء على الاختلافات الرئيسية بين محرك الدمى والسيلينيوم في الجدول أدناه. بعد ذلك، سوف نتعمق في التفاصيل ونقدم مثالًا مقتطفًا لكل إطار لإثبات فعاليته في استخراج البيانات من صفحات الويب.
معايير | محرك الدمى | السيلينيوم |
---|---|---|
اللغات المتوافقة | يتم دعم JavaScript فقط رسميًا، ولكن هناك منافذ PHP وPython غير رسمية | Java، وPython، وC#، وRuby، وPHP، وJavaScript، وKotlin |
دعم المتصفح | دعم الكروم وفايرفوكس التجريبي | كروم، وسفاري، وفايرفوكس، وأوبرا، وإيدج، وإنترنت إكسبلورر |
أداء | 60% أسرع من السيلينيوم | سريع |
دعم نظام التشغيل | ويندوز، لينكس، وماك | ويندوز، لينكس، ماك، وسولاريس |
بنيان | بنية تعتمد على الأحداث مع مثيلات المتصفح بدون رأس | بروتوكول JSONWire على برنامج تشغيل الويب للتحكم في مثيل المتصفح |
المتطلبات الأساسية | حزمة جافا سكريبت كافية | روابط السيلينيوم (للغة البرمجة المحددة) وبرامج تشغيل الويب للمتصفح |
مجتمع | مجتمع أصغر مقارنة بالسيلينيوم | وثائق راسخة ومجتمع كبير |
دعنا ننتقل إلى مناقشة هذه المكتبات بالتفصيل ونجري مثالًا على كل منها لتوضيح كفاءتها في استخراج البيانات من صفحة الويب.
محرك الدمى
محرك الدمى هي مكتبة Node.js التي توفر واجهة برمجة تطبيقات عالية المستوى للتحكم في Chrome أو Chromium عبر بروتوكول DevTools. وهو مصمم لأتمتة المهام في Chrome أو Chromium، مثل التقاط لقطات الشاشة وإنشاء ملفات PDF والتنقل بين الصفحات.
يمكن أيضًا استخدام محرك الدمى لاختبار صفحات الويب من خلال محاكاة تفاعلات المستخدم مثل النقر على الأزرار وملء النماذج والتحقق من النتائج المعروضة.
مزايا محرك الدمى
- سهولة الاستعمال: بسيطة وسهلة الاستخدام.
- المجمعة مع الكروم: لا يلزم أي إعداد إضافي.
- وضع مقطوعة الرأس: يعمل في وضع مقطوعة الرأس بشكل افتراضي ولكن يمكن تهيئته للتشغيل في وضع المتصفح الكامل.
- العمارة الموجهة بالحدث: يلغي الحاجة إلى مكالمات النوم اليدوية في التعليمات البرمجية الخاصة بك.
- القدرات الشاملة: يمكنه التقاط لقطات شاشة وإنشاء ملفات PDF وأتمتة جميع إجراءات المتصفح.
- ادارة الأداء: يوفر أدوات لتسجيل وقت التشغيل وتحميل الأداء لتحسين وتصحيح مكشطة الخاص بك.
- زحف SPA: قادر على الزحف إلى تطبيقات الصفحة الواحدة (SPA) وإنشاء محتوى معروض مسبقًا (العرض من جانب الخادم).
- تسجيل البرنامج النصي: يسمح بإنشاء نصوص برمجية لمحرك الدمى عن طريق تسجيل الإجراءات على المتصفح باستخدام وحدة تحكم DevTools.
عيوب محرك الدمى
- دعم محدود للمتصفح: يدعم عددًا أقل من المتصفحات مقارنة بالسيلينيوم.
- جافا سكريبت تركز: يدعم JavaScript بشكل أساسي، على الرغم من وجود منافذ غير رسمية لـ Python وPHP.
مثال على تجريف الويب باستخدام محرك الدمى
هيا بنا نستعرض برنامجًا تعليميًا لاستخلاص البيانات من الويب لمحرك الدمى لاستخراج العناصر من فئة الجريمة والإثارة على موقع الدانوب الإلكتروني.
متجر الدانوب: الجريمة والإثارة
للبدء، قم باستيراد وحدة محرك الدمى وأنشئ وظيفة غير متزامنة لتشغيل كود محرك الدمى:
const puppeteer = require('puppeteer');
async function main() {
// Launch a headless browser instance
const browser = await puppeteer.launch({ headless: true });
// Create a new page object
const page = await browser.newPage();
// Navigate to the target URL and wait until the loading finishes
await page.goto('https://danube-webshop.herokuapp.com/', { waitUntil: 'networkidle2' });
// Wait for the left-side bar to load
await page.waitForSelector('ul.sidebar-list');
// Click on the first element and wait for the navigation to finish
await Promise.all([
page.waitForNavigation(),
page.click("ul[class='sidebar-list'] > li > a"),
]);
// Wait for the book previews to load
await page.waitForSelector("li[class='preview']");
// Extract the book previews
const books = await page.evaluateHandle(
() => [...document.querySelectorAll("li[class='preview']")]
);
// Extract the relevant data using page.evaluate
const processed_data = await page.evaluate(elements => {
let data = [];
elements.forEach(element => {
let title = element.querySelector("div.preview-title").innerHTML;
let author = element.querySelector("div.preview-author").innerHTML;
let rating = element.querySelector("div.preview-details > p.preview-rating").innerHTML;
let price = element.querySelector("div.preview-details > p.preview-price").innerHTML;
let result = { title, author, rating, price };
data.push(result);
});
return data;
}, books);
// Print out the extracted data
console.log(processed_data);
// Close the page and browser respectively
await page.close();
await browser.close();
}
// Run the main function to scrape the data
main();
الناتج المتوقع
عند تشغيل التعليمات البرمجية، يجب أن يشبه الإخراج ما يلي:
[
{
title: 'Does the Sun Also Rise?',
author: 'Ernst Doubtingway',
rating: '★★★★☆',
price: '$9.95'
},
{
title: 'The Insiders',
author: 'E. S. Hilton',
rating: '★★★★☆',
price: '$9.95'
},
{
title: 'A Citrussy Clock',
author: 'Bethany Urges',
rating: '★★★★★',
price: '$9.95'
}
]
مثال آخر لاستخدام محرك الدمى
بالإضافة إلى استخراج البيانات من صفحات الويب، يمكن استخدام محرك الدمى لمجموعة متنوعة من مهام الأتمتة. إحدى حالات الاستخدام الشائعة هي إنشاء ملف PDF لصفحة ويب. دعنا نستعرض مثالًا حيث يتم استخدام محرك الدمى لإنشاء ملف PDF من صفحة ويب.
إنشاء ملف PDF باستخدام محرك الدمى
الخطوة 1: استيراد محرك الدمى وإنشاء وظيفة غير متزامنة
const puppeteer = require('puppeteer');
async function generatePDF() {
// Launch a headless browser instance
const browser = await puppeteer.launch({ headless: true });
// Create a new page object
const page = await browser.newPage();
// Navigate to the target URL
await page.goto('https://example.com', { waitUntil: 'networkidle2' });
// Generate a PDF from the web page
await page.pdf({
path: 'example.pdf', // Output file path
format: 'A4', // Paper format
printBackground: true, // Include background graphics
});
// Close the page and browser respectively
await page.close();
await browser.close();
}
// Run the function to generate the PDF
generatePDF();
خيارات إضافية لمحرك الدمى
يوفر Puppeteer العديد من الخيارات لإنشاء ملفات PDF التي يمكن تخصيصها لتناسب احتياجاتك. فيما يلي بعض الخيارات التي يمكنك استخدامها:
path
: مسار الملف لحفظ ملف PDF.format
: تنسيق الورق (على سبيل المثال، "A4"، "Letter").printBackground
: ما إذا كان سيتم تضمين رسومات الخلفية.landscape
: ضبط لtrue
لتوجيه المناظر الطبيعية.margin
: حدد هوامش ملف PDF (أعلى، يمين، أسفل، يسار).
مثال مع خيارات إضافية:
const puppeteer = require('puppeteer');
async function generatePDF() {
const browser = await puppeteer.launch({ headless: true });
const page = await browser.newPage();
await page.goto('https://example.com', { waitUntil: 'networkidle2' });
await page.pdf({
path: 'example.pdf',
format: 'A4',
printBackground: true,
landscape: true,
margin: {
top: '20px',
right: '20px',
bottom: '20px',
left: '20px',
},
});
await page.close();
await browser.close();
}
generatePDF();
إخراج المثال
سيؤدي تشغيل الكود أعلاه إلى إنشاء ملف PDF اسمه example.pdf
في الدليل الحالي بمحتويات صفحة الويب https://example.com
.
Puppeteer هي أداة متعددة الاستخدامات لمهام أتمتة الويب، بدءًا من استخراج البيانات وحتى إنشاء ملفات PDF. إن سهولة استخدامه وميزاته القوية تجعله خيارًا ممتازًا لأتمتة مجموعة واسعة من أنشطة المتصفح. سواء كنت تقوم باستخلاص البيانات، أو إنشاء التقارير، أو اختبار صفحات الويب، فإن Puppeteer يوفر الأدوات التي تحتاجها لإنجاز المهمة بكفاءة.
السيلينيوم
السيلينيوم هي أداة اختبار شاملة ومفتوحة المصدر وأداة لأتمتة الويب تُستخدم غالبًا لتجميع الويب. وتشمل مكوناته الرئيسية السيلينيوم IDE، السيلينيوم WebDriver، وشبكة السيلينيوم.
- بيئة تطوير متكاملة للسيلينيوم: يستخدم لتسجيل الإجراءات قبل أتمتتها.
- برنامج تشغيل الويب السيلينيوم: ينفذ الأوامر في المتصفح.
- شبكة السيلينيوم: تمكين التنفيذ المتوازي.
فوائد السيلينيوم
- سهولة الاستعمال: بسيطة وسهلة الاستخدام.
- دعم اللغة: يدعم لغات البرمجة المختلفة مثل Python، Java، JavaScript، Ruby، وC#.
- أتمتة المتصفح: يمكن أتمتة المتصفحات مثل Firefox وEdge وSafari وحتى متصفحات QtWebKit المخصصة.
- قابلية التوسع: من الممكن توسيع نطاق السيلينيوم إلى مئات الحالات باستخدام خوادم سحابية بإعدادات متصفح مختلفة.
- عبر منصة: يعمل على أنظمة التشغيل Windows وmacOS وLinux.
عيوب السيلينيوم
- الإعداد المعقد: يمكن أن تكون طرق إعداد السيلينيوم معقدة.
عينة تجريف الويب مع السيلينيوم
كما هو الحال مع محرك الدمى، فلنستعرض برنامجًا تعليميًا حول تجريف الويب باستخدام السيلينيوم باستخدام نفس الموقع المستهدف. سنقوم باستخراج معاينات الكتاب من فئة الجريمة والإثارة على موقع الدانوب.
متجر الدانوب: الجريمة والإثارة
الخطوة 1: استيراد الوحدات الضرورية وتكوين السيلينيوم
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
options = webdriver.ChromeOptions()
options.add_argument("--headless")
الخطوة 2: تهيئة Chrome WebDriver
driver = webdriver.Chrome(options=options)
الخطوة 3: انتقل إلى موقع الويب المستهدف
time.sleep(1)
crime_n_thrillers = driver.find_element(By.CSS_SELECTOR, "ul[class='sidebar-list'] > li")
crime_n_thrillers.click()
time.sleep(1)
books = driver.find_elements(By.CSS_SELECTOR, "div.shop-content li.preview")
الخطوة 4: انقر فوق فئة Crime & Thrillers واستخرج معاينة الكتاب
time.sleep(1)
crime_n_thrillers = driver.find_element(By.CSS_SELECTOR, "ul[class='sidebar-list'] > li")
crime_n_thrillers.click()
time.sleep(1)
books = driver.find_elements(By.CSS_SELECTOR, "div.shop-content li.preview")
الخطوة 5: تحديد وظيفة لاستخراج البيانات من كل معاينة كتاب
def extract(element):
title = element.find_element(By.CSS_SELECTOR, "div.preview-title").text
author = element.find_element(By.CSS_SELECTOR, "div.preview-author").text
rating = element.find_element(By.CSS_SELECTOR, "div.preview-details p.preview-rating").text
price = element.find_element(By.CSS_SELECTOR, "div.preview-details p.preview-price").text
return {"title": title, "author": author, "rating": rating, "price": price}
الخطوة 6: قم بالمرور عبر المعاينات واستخرج البيانات وقم بإنهاء برنامج التشغيل
extracted_data = []
for element in books:
data = extract(element)
extracted_data.append(data)
print(extracted_data)
driver.quit()
الناتج المتوقع
سيؤدي تشغيل الكود أعلاه إلى إنتاج مخرجات مشابهة لما يلي:
[
{'title': 'Does the Sun Also Rise?', 'author': 'Ernst Doubtingway', 'rating': '★★★★☆', 'price': '$9.95'},
{'title': 'The Insiders', 'author': 'E. S. Hilton', 'rating': '★★★★☆', 'price': '$9.95'},
{'title': 'A Citrussy Clock', 'author': 'Bethany Urges', 'rating': '★★★★★', 'price': '$9.95'}
]
مثال إضافي على السيلينيوم: التقاط لقطة شاشة
بالإضافة إلى استخراج البيانات، يمكن أيضًا استخدام السيلينيوم لالتقاط لقطات شاشة لصفحات الويب. فيما يلي مثال لكيفية التقاط لقطة شاشة لصفحة ويب باستخدام السيلينيوم.
الخطوة 1: استيراد الوحدات الضرورية وتكوين السيلينيوم
from selenium import webdriver
options = webdriver.ChromeOptions()
options.add_argument("--headless")
الخطوة 2: تهيئة Chrome WebDriver
driver = webdriver.Chrome(options=options)
الخطوة 3: انتقل إلى موقع الويب المستهدف
url = "https://example.com"
driver.get(url)
الخطوة 4: التقط لقطة للشاشة
driver.save_screenshot("example_screenshot.png")
الخطوة 5: قم بإنهاء السائق
driver.quit()
السيلينيوم هو أداة متعددة الاستخدامات لمهام أتمتة الويب، بما في ذلك تجريف الويب والتقاط لقطات الشاشة. إن دعمه للعديد من لغات البرمجة والمتصفحات، إلى جانب قابليته للتوسع، يجعله خيارًا قويًا لتلبية احتياجات الأتمتة المتنوعة. سواء كنت تقوم باستخراج البيانات أو إنشاء التقارير، يوفر السيلينيوم الإمكانيات اللازمة لأتمتة مهامك بكفاءة.
محرك الدمى مقابل السيلينيوم: مقارنة السرعة
هل محرك الدمى أسرع من السيلينيوم؟ الجواب هو نعم، محرك الدمى أسرع بشكل عام من السيلينيوم.
لمقارنة سرعة Puppeteer وSelenium، استخدمنا وضع الحماية الخاص بمتجر Danube وقمنا بتشغيل النصوص المقدمة أكثر من 20 مرة، مع متوسط أوقات التنفيذ.
اختبار سرعة السيلينيوم
استخدمنا time
وحدة في بايثون لقياس وقت تنفيذ البرنامج النصي السيلينيوم. تم تسجيل وقت البدء في البداية ووقت الانتهاء في نهاية البرنامج النصي. يوفر الفرق بين هذه الأوقات إجمالي مدة التنفيذ.
فيما يلي النص الكامل المستخدم للسيلينيوم:
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
def extract(element):
title = element.find_element(By.CSS_SELECTOR, "div.preview-title").text
author = element.find_element(By.CSS_SELECTOR, "div.preview-author").text
rating = element.find_element(By.CSS_SELECTOR, "div.preview-details p.preview-rating").text
price = element.find_element(By.CSS_SELECTOR, "div.preview-details p.preview-price").text
return {"title": title, "author": author, "rating": rating, "price": price}
# Start the timer
start_time = time.time()
options = webdriver.ChromeOptions()
options.add_argument("--headless")
# Create a new instance of the Chrome driver
driver = webdriver.Chrome(options=options)
url = "https://danube-webshop.herokuapp.com/"
driver.get(url)
# Click on the Crime & Thrillers category
time.sleep(1)
crime_n_thrillers = driver.find_element(By.CSS_SELECTOR, "ul[class='sidebar-list'] > li")
crime_n_thrillers.click()
time.sleep(1)
# Extract the book previews
books = driver.find_elements(By.CSS_SELECTOR, "div.shop-content li.preview")
extracted_data = []
for element in books:
data = extract(element)
extracted_data.append(data)
print(extracted_data)
# End the timer
end_time = time.time()
print(f"The whole script took: {end_time - start_time:.4f} seconds")
driver.quit()
اختبار سرعة محرك الدمى
بالنسبة للنص البرمجي لمحرك الدمى، استخدمنا Date
كائن لقياس وقت التنفيذ. تم تسجيل وقت البدء في البداية ووقت الانتهاء في نهاية البرنامج النصي. يوفر الفرق بين هذه الأوقات إجمالي مدة التنفيذ.
فيما يلي النص الكامل المستخدم لـ Puppeteer:
const puppeteer = require('puppeteer');
async function main() {
const start = Date.now();
const browser = await puppeteer.launch({ headless: true });
const page = await browser.newPage();
await page.goto('https://danube-webshop.herokuapp.com/', { waitUntil: 'networkidle2' });
await page.waitForSelector('ul.sidebar-list');
await Promise.all([
page.waitForNavigation(),
page.click("ul[class='sidebar-list'] > li > a"),
]);
await page.waitForSelector("li[class='preview']");
const books = await page.evaluateHandle(
() => [...document.querySelectorAll("li[class='preview']")]
);
const processed_data = await page.evaluate(elements => {
let data = [];
elements.forEach(element => {
let title = element.querySelector("div.preview-title").innerHTML;
let author = element.querySelector("div.preview-author").innerHTML;
let rating = element.querySelector("div.preview-details > p.preview-rating").innerHTML;
let price = element.querySelector("div.preview-details > p.preview-price").innerHTML;
let result = { title, author, rating, price };
data.push(result);
});
return data;
}, books);
console.log(processed_data);
await page.close();
await browser.close();
const end = Date.now();
console.log(`Execution time: ${(end - start) / 1000} seconds`);
}
main();
نتائج اختبار الأداء
أظهرت اختبارات الأداء أن محرك الدمى أسرع بحوالي 60% من السيلينيوم. ميزة السرعة هذه تجعل من Puppeteer خيارًا أكثر ملاءمة للمشاريع التي تتطلب أتمتة واستخلاص الويب بسرعة عالية، خاصة عند العمل مع المتصفحات المستندة إلى Chromium.
ملخص نتائج السرعة:
يوضح الرسم البياني أدناه فرق الأداء بين Puppeteer وSelenium:
يعد توسيع نطاق تطبيقات Puppeteer للمشاريع التي تتطلب عملية تجريف سريعة وفعالة للويب هو الخيار الأمثل في هذا السياق.
محرك الدمى مقابل السيلينيوم: أيهما أفضل؟
إذن أيهما أفضل بين السيلينيوم ومحرك الدمى في الكشط؟ لا توجد إجابة مباشرة على هذا السؤال لأنه يعتمد على عوامل متعددة، مثل دعم المكتبة على المدى الطويل، والدعم عبر المتصفحات، واحتياجاتك لتجميع الويب.
يعد Puppeteer أسرع، ولكن بالمقارنة مع السيلينيوم، فإنه يدعم عددًا أقل من المتصفحات. يدعم السيلينيوم أيضًا المزيد من لغات البرمجة مقارنةً بـ Puppeteer.
خاتمة
على الرغم من أن استخدام Puppeteer أو Selenium يعد خيارًا جيدًا لتخريب الويب، إلا أن توسيع نطاق مشروع تجريف الويب الخاص بك وتحسينه قد يمثل تحديًا لأن إجراءات مكافحة الروبوتات المتقدمة يمكنها اكتشاف هذه المكتبات وحظرها. أفضل طريقة لتجنب ذلك هي استخدام واجهة برمجة تطبيقات الويب، مثل OneProxy.
استخدام محرك الدمى مع الخوادم الوكيلة
لاستخدام Puppeteer مع خادم وكيل، يمكنك تمرير إعدادات الوكيل في ملف args
الخيار عند تشغيل مثيل المتصفح. هنا مثال:
const puppeteer = require('puppeteer');
async function main() {
const proxyServer = 'http://your-proxy-server:port';
const browser = await puppeteer.launch({
headless: true,
args: [`--proxy-server=${proxyServer}`]
});
const page = await browser.newPage();
await page.goto('https://example.com', { waitUntil: 'networkidle2' });
// Perform your web scraping tasks here
await browser.close();
}
main();
استخدام السيلينيوم مع الخوادم الوكيلة
لاستخدام السيلينيوم مع خادم وكيل، يمكنك ضبط خيارات الوكيل باستخدام webdriver.Proxy
فصل. هنا مثال:
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy, ProxyType
proxy = Proxy()
proxy.proxy_type = ProxyType.MANUAL
proxy.http_proxy = "your-proxy-server:port"
proxy.ssl_proxy = "your-proxy-server:port"
capabilities = webdriver.DesiredCapabilities.CHROME
proxy.add_to_capabilities(capabilities)
options = webdriver.ChromeOptions()
options.add_argument("--headless")
driver = webdriver.Chrome(desired_capabilities=capabilities, options=options)
driver.get("https://example.com")
# Perform your web scraping tasks here
driver.quit()
يمكن أن يساعد استخدام خوادم بروكسي مع Puppeteer وSelenium في تجاوز القيود المستندة إلى IP وتقليل خطر الحظر، مما يعزز كفاءة مهام استخراج الويب الخاصة بك. وكلاء OneProxy الدوارون يمكن تحسين هذه العملية بشكل أكبر، مما يوفر تجربة تجريف سلسة.