Playwright: تجميع البيانات من الويب واختبارها
تعلم تلقين المتصفح لاختبارات & استخراج البيانات
Playwright هو إطار عمل قوي وحديث لتشغيل المتصفحات يُحدث ثورة في عمليات تجميع البيانات من الويب واختبارات نهاية إلى نهاية.
تم تطويره بواسطة مايكروسوفت، ويقدم واجهة برمجة تطبيقات موحدة لتشغيل متصفحات Chromium (بما في ذلك Chrome و Edge)، و Firefox، و WebKit (Safari) مع موثوقية وسرعة غير مسبوقة.

ما هو Playwright؟
Playwright هو إطار عمل مفتوح المصدر لتشغيل المتصفحات يمكّن المطورين من كتابة اختبارات نهاية إلى نهاية موثوقة وبناء حلول معقدة لتجميع البيانات من الويب. على عكس أدوات التحكم التلقائي التقليدية، تم بناء Playwright من الصفر لمعالجة تطبيقات الويب الحديثة التي تحتوي على محتوى ديناميكي وتطبيقات ويب تطبيقية (SPAs) وتقنيات JavaScript المعقدة.
يتعامل الإطار مع المشكلة الأساسية التي كانت تؤثر على أدوات التحكم التلقائي السابقة: عدم الاستقرار. Playwright ي introduce آليات الانتظار التلقائي التي تنتظر تلقائيًا عنصرًا ليصبح قابلًا للتفاعل قبل أداء أي عملية، مما يزيل الحاجة إلى مهلات عشوائية أو عبارات النوم التي جعلت الاختبارات غير موثوقة.
الميزات الرئيسية
الدعم عبر المتصفحات: يدعم Playwright جميع محركات المتصفحات الرئيسية - Chromium (بما في ذلك Chrome و Edge)، و Firefox، و WebKit (Safari). هذا يعني أنه يمكنك كتابة نص برمجي للتحكم التلقائي مرة واحدة وإجراؤه عبر متصفحات مختلفة دون تعديل، مما يضمن أن تطبيقات الويب تعمل بشكل متسق في كل مكان.
الانتظار التلقائي: واحدة من أقوى ميزات Playwright هي آليته التلقائية للانتظار. قبل أداء أي عملية، ينتظر Playwright تلقائيًا حتى يصبح العنصر مرئيًا، مفعّلًا، مستقرًا، وغير مخفي. هذا يزيل الظروف التنافسية ويجعل الاختبارات أكثر موثوقية بشكل كبير مقارنة بالأدوات مثل Selenium حيث يكون من الضروري غالبًا الانتظار بشكل صريح.
التقاط الشبكة: يسمح Playwright بتقاط، تعديل، ومحاكاة طلبات الشبكة والردود. هذا أمر لا غنى عنه لاختبار الحالات الحدودية، محاكاة الشبكات البطيئة، حظر الموارد غير الضرورية أثناء تجميع البيانات، أو محاكاة استجابات واجهات برمجة التطبيقات دون الحاجة إلى خلفية.
محاكاة الأجهزة المحمولة: اختبر تطبيقات الويب المحمولة من خلال محاكاة أجهزة محمولة مختلفة ذات أحجام شاشة محددة، وكلمات معرف المستخدم، وحدث اللمس. يحتوي Playwright على وصفات الأجهزة لiphones وTablets شائعة.
المحددات القوية: بالإضافة إلى محددات CSS وXPath، يدعم Playwright محددات النص، ومحددات القواعد بناءً على الوصول، وحتى محددات تجريبية لـ React وVue لتطبيقات القواعد.
التثبيت والتكوين
تثبيت Playwright سهل عبر لغات البرمجة المختلفة.
تثبيت Python
للمشاريع المبنية على Python، يمكن تثبيت Playwright عبر pip، وتشمل كل من الواجهات البرمجية المتزامنة وغير المتزامنة. إذا كنت تبحث عن مدير حزم ومشاريع وبيئات Python أسرع وأكثر حداثة، فراجع دليلنا حول uv - مدير حزم Python، ومشاريع، وبيئات:
# تثبيت حزمة Playwright
pip install playwright
# تثبيت المتصفحات (Chromium، Firefox، WebKit)
playwright install
# لتثبيت متصفح معين فقط
playwright install chromium
للحصول على مرجع شامل لقواعد Python وال الأوامر الشائعة أثناء العمل مع Playwright، راجع ورقة ملاحظات Python.
تثبيت JavaScript/TypeScript
للمشاريع المبنية على Node.js، قم بتثبيت Playwright عبر npm أو yarn:
# باستخدام npm
npm init playwright@latest
# باستخدام yarn
yarn create playwright
# التثبيت اليدوي
npm install -D @playwright/test
npx playwright install
يقدم أمر npm init playwright تكوينًا تفاعليًا يضبط مشروعك مع اختبارات مثالية، ملفات التكوين، وتدفق عمل GitHub Actions.
التكوين الأساسي
أنشئ ملفًا playwright.config.ts (TypeScript) أو playwright.config.js (JavaScript):
import { defineConfig, devices } from '@playwright/test';
export default defineConfig({
testDir: './tests',
timeout: 30000,
retries: 2,
workers: 4,
use: {
headless: true,
viewport: { width: 1280, height: 720 },
screenshot: 'only-on-failure',
video: 'retain-on-failure',
},
projects: [
{
name: 'chromium',
use: { ...devices['Desktop Chrome'] },
},
{
name: 'firefox',
use: { ...devices['Desktop Firefox'] },
},
{
name: 'webkit',
use: { ...devices['Desktop Safari'] },
},
],
});
تجميع البيانات من الويب باستخدام Playwright
يتفوق Playwright في تجميع البيانات من الويب، خاصةً لites الحديثة التي تحتوي على محتوى ديناميكي تجد صعوبة في التعامل معها مكتبات تجميع البيانات التقليدية.
مثال أساسي لتجميع البيانات
إليك مثالًا شاملًا بلغة Python يوضح مفاهيم تجميع البيانات الأساسية:
from playwright.sync_api import sync_playwright
import json
def scrape_website():
with sync_playwright() as p:
# تشغيل المتصفح
browser = p.chromium.launch(headless=True)
# إنشاء سياق للعزل
context = browser.new_context(
viewport={'width': 1920, 'height': 1080},
user_agent='Mozilla/5.0 (Windows NT 10.0; Win64; x64)'
)
# فتح صفحة جديدة
page = context.new_page()
# الانتقال إلى عنوان URL
page.goto('https://example.com/products')
# الانتظار حتى تتم تحميل المحتوى
page.wait_for_selector('.product-item')
# استخراج البيانات
products = page.query_selector_all('.product-item')
data = []
for product in products:
title = product.query_selector('h2').inner_text()
price = product.query_selector('.price').inner_text()
url = product.query_selector('a').get_attribute('href')
data.append({
'title': title,
'price': price,
'url': url
})
# التنظيف
browser.close()
return data
# تشغيل مُجمِّع البيانات
results = scrape_website()
print(json.dumps(results, indent=2))
التعامل مع المحتوى الديناميكي
غالبًا ما تُحمّل المواقع الحديثة المحتوى بشكل ديناميكي عبر JavaScript. يتعامل Playwright مع هذا بسلاسة:
async def scrape_dynamic_content():
async with async_playwright() as p:
browser = await p.chromium.launch()
page = await browser.new_page()
await page.goto('https://example.com/infinite-scroll')
# التمرير لتحميل المزيد من المحتوى
for _ in range(5):
await page.evaluate('window.scrollTo(0, document.body.scrollHeight)')
await page.wait_for_timeout(2000)
# الانتظار حتى تصبح الشبكة خاملة
await page.wait_for_load_state('networkidle')
# استخراج جميع العناصر المحمّلة
items = await page.query_selector_all('.item')
await browser.close()
تحويل المحتوى المجمّع إلى Markdown
بعد استخراج المحتوى HTML باستخدام Playwright، غالبًا ما تحتاج إلى تحويله إلى تنسيق أكثر قابلية للاستخدام. للحصول على دليل شامل حول تحويل HTML إلى Markdown، راجع مقالاتنا حول تحويل HTML إلى Markdown باستخدام Python: دليل شامل والتي تقارن 6 مكتبات Python المختلفة، وتحويل محتوى HTML إلى Markdown باستخدام LLM وOllama لتحويل مدعوم بالذكاء الاصطناعي. إذا كنت تعمل مع مستندات Word بدلًا من ذلك، فراجع دليلنا حول تحويل مستندات Word إلى Markdown.
المصادقة وإدارة الجلسات
عندما يتطلب تجميع البيانات المصادقة، يجعل Playwright من السهل حفظ وإعادة استخدام حالة المتصفح:
def login_and_save_session():
with sync_playwright() as p:
browser = p.chromium.launch(headless=False)
context = browser.new_context()
page = context.new_page()
# تسجيل الدخول
page.goto('https://example.com/login')
page.fill('input[name="username"]', 'your_username')
page.fill('input[name="password"]', 'your_password')
page.click('button[type="submit"]')
# الانتظار حتى يتم التوجيه بعد تسجيل الدخول
page.wait_for_url('**/dashboard')
# حفظ الحالة المصادقة
context.storage_state(path='auth_state.json')
browser.close()
def scrape_with_saved_session():
with sync_playwright() as p:
browser = p.chromium.launch()
# إعادة استخدام الحالة المصادقة المحفوظة
context = browser.new_context(storage_state='auth_state.json')
page = context.new_page()
# مصادقة بالفعل!
page.goto('https://example.com/protected-data')
# ... استخراج المحتوى المحمي
browser.close()
هذا النهج مفيد بشكل خاص عند العمل مع واجهات برمجة التطبيقات أو بناء خوادم MCP للتكامل مع أدوات الذكاء الاصطناعي. للحصول على دليل شامل حول تنفيذ تجميع البيانات في تكامل أدوات الذكاء الاصطناعي، راجع مقالتنا حول بناء خوادم MCP في Python: البحث على الويب وجمع البيانات.
اختبارات نهاية إلى نهاية
الاستخدام الرئيسي لـ Playwright هو كتابة اختبارات متينة نهاية إلى نهاية لتطبيقات الويب.
كتابة اختبارك الأول
إليك مثالًا كاملًا لاختبار في TypeScript:
import { test, expect } from '@playwright/test';
test('يمكن للمستخدم إضافة عنصر إلى السلة', async ({ page }) => {
// الانتقال إلى الصفحة الرئيسية
await page.goto('https://example-shop.com');
// البحث عن المنتج
await page.fill('[data-testid="search-input"]', 'laptop');
await page.press('[data-testid="search-input"]', 'Enter');
// الانتظار حتى تظهر نتائج البحث
await expect(page.locator('.product-card')).toBeVisible();
// النقر على المنتج الأول
await page.locator('.product-card').first().click();
// التحقق من أن الصفحة تم تحميلها
await expect(page).toHaveURL(/\/product\/.+/);
// إضافة إلى السلة
await page.click('[data-testid="add-to-cart"]');
// التحقق من تحديث السلة
const cartCount = page.locator('[data-testid="cart-count"]');
await expect(cartCount).toHaveText('1');
});
نموذج الصفحة (Page Object Model)
للمجموعات الكبيرة من الاختبارات، استخدم نموذج الصفحة (Page Object Model) لتحسين الحفظ:
// pages/LoginPage.ts
export class LoginPage {
constructor(private page: Page) {}
async navigate() {
await this.page.goto('/login');
}
async login(username: string, password: string) {
await this.page.fill('[name="username"]', username);
await this.page.fill('[name="password"]', password);
await this.page.click('button[type="submit"]');
}
async getErrorMessage() {
return await this.page.locator('.error-message').textContent();
}
}
// tests/login.spec.ts
import { test, expect } from '@playwright/test';
import { LoginPage } from '../pages/LoginPage';
test('تسجيل الدخول باستخدام بيانات غير صحيحة يعرض خطأ', async ({ page }) => {
const loginPage = new LoginPage(page);
await loginPage.navigate();
await loginPage.login('invalid@email.com', 'wrongpass');
const error = await loginPage.getErrorMessage();
expect(error).toContain('بيانات الدخول غير صحيحة');
});
الميزات المتقدمة
Codegen - توليد الاختبارات تلقائيًا
يولد أداة Codegen في Playwright الاختبارات من خلال تسجيل التفاعلات الخاصة بك مع صفحة الويب:
# فتح Codegen
playwright codegen example.com
# مع متصفح معين
playwright codegen --browser firefox example.com
# مع حالة المصادقة المحفوظة
playwright codegen --load-storage=auth.json example.com
بينما تتفاعل مع الصفحة، يولد Codegen الكود في الوقت الفعلي. هذا مفيد جدًا لتصميم الاختبارات بسرعة أو تعلم لغة اختيار Playwright.
مستعرض Trace Viewer للاستكشاف
عندما تفشل الاختبارات، يمكن أن يكون من الصعب فهم السبب. يوفر مستعرض Trace Viewer في Playwright رؤية زمنية لتشغيل الاختبار:
// تفعيل التتبع في التكوين
use: {
trace: 'on-first-retry',
}
بعد أن يفشل الاختبار ويحاول إعادة التشغيل، اعرض التتبع:
playwright show-trace trace.zip
يعرض مستعرض Trace Viewer صورًا لكل عملية، نشاط الشبكة، سجلات وحدة التحكم، وصور DOM، مما يجعل الاستكشاف سهلًا.
التقاط الشبكة والمحاكاة
تقطيع وتعديل حركة المرور الشبكية لاختبار الحالات الحدودية:
def test_with_mocked_api():
with sync_playwright() as p:
browser = p.chromium.launch()
page = browser.new_page()
# محاكاة استجابة API
def handle_route(route):
if 'api/products' in route.request.url:
route.fulfill(
status=200,
body=json.dumps({
'products': [
{'id': 1, 'name': 'منتج اختبار', 'price': 99.99}
]
})
)
else:
route.continue_()
page.route('**/*', handle_route)
page.goto('https://example.com')
# الصفحة الآن تستخدم البيانات المُحاكاة
browser.close()
اختبار الأجهزة المحمولة
اختبار التصميمات المرنة على أجهزة مختلفة:
from playwright.sync_api import sync_playwright
def test_mobile():
with sync_playwright() as p:
# استخدام وصف الأجهزة
iphone_13 = p.devices['iPhone 13']
browser = p.webkit.launch()
context = browser.new_context(**iphone_13)
page = context.new_page()
page.goto('https://example.com')
# التفاعل كمستخدم محمول
page.locator('#mobile-menu-button').click()
browser.close()
أفضل الممارسات
لجمع البيانات من الويب
- استخدم وضع المتصفح بدون واجهة في الإنتاج: يوفر المتصفح بدون واجهة سرعة أكبر ويستخدم موارد أقل
- تطبيق الحد من التكرار: احترم المواقع المستهدفة مع تأخير بين الطلبات
- التعامل مع الأخطاء بسلاسة: تحدث الأخطاء مثل مشاكل الشبكة، والمهلات، وتغييرات المحددات
- تكرار وكلاء المستخدم: تجنب الكشف عن طريق تغيير بصمة المتصفح
- احترم robots.txt: تحقق واتبع سياسات تجميع البيانات للمواقع
- استخدم العزل عبر السياق: أنشئ سياقات متصفح منفصلة لجمع البيانات المتوازية
عند تحويل المحتوى المجمّع إلى تنسيق Markdown، فكّر في استخدام أدوات تحويل قائمة على الذكاء الاصطناعي أو مكتبات Python المتخصصة في تحويل HTML إلى Markdown للحصول على إخراج نظيف.
للاختبار
- استخدم سمات data-testid: أكثر استقرارًا من الفئات CSS التي تختلف غالبًا
- تجنب الانتظار الصريح: استخدم آليات الانتظار المدمجة في Playwright بدلًا من
sleep() - احتفظ بالاختبارات مستقلة: يجب أن يكون لكل اختبار القدرة على التشغيل بشكل منفرد
- استخدم المكونات: مشاركة كود الإعداد بين الاختبارات بكفاءة
- تشغيل الاختبارات بالتوازي: استغل خيوط Playwright للسرعة
- سجّل التتبع عند الفشل: تفعيل تسجيل التتبع لتسهيل الاستكشاف
تحسين الأداء
# تعطيل الموارد غير الضرورية
def fast_scraping():
with sync_playwright() as p:
browser = p.chromium.launch()
context = browser.new_context()
page = context.new_page()
# حظر الصور والأنماط لتسريع جمع البيانات
async def block_resources(route):
if route.request.resource_type in ['image', 'stylesheet', 'font']:
await route.abort()
else:
await route.continue_()
page.route('**/*', block_resources)
page.goto('https://example.com')
browser.close()
مقارنة Playwright مع البديل
Playwright مقابل Selenium
مزايا Playwright:
- الانتظار التلقائي المدمج يزيل اختبارات غير موثوقة
- أسرع تنفيذ بسبب العمارة الحديثة
- أفضل التقاط الشبكة والمحاكاة
- أدوات استكشاف أفضل (Trace Viewer)
- واجهة برمجة تطبيقات أبسط مع أقل كود تكراري
- دعم متعدد للمتصفحات مع تثبيت واحد
مزايا Selenium:
- بيئة أكثر نضجًا مع مجتمع واسع
- دعم لعدد أكبر من لغات البرمجة
- توافق أفضل مع المتصفحات بما في ذلك الإصدارات الأقدم
Playwright مقابل Puppeteer
مزايا Playwright:
- دعم حقيقي عبر المتصفحات (Firefox، WebKit، Chromium)
- تصميم واجهة برمجة تطبيقات أفضل بناءً على دروس Puppeteer
- أدوات استكشاف أكثر قوة
- دعم من مايكروسوفت والتطوير النشط
مزايا Puppeteer:
- حجم أصغر قليلاً
- خبرة في بروتوكول Chrome DevTools
للمشاريع الجديدة، يُوصى بـ Playwright بشكل عام بسبب هيكله الحديث ومجموعة ميزاته الشاملة. إذا كنت تعمل مع Go بدلًا من Python أو JavaScript وتحتاج إلى قدرات تجميع البيانات، فراجع دليلنا حول بدائل BeautifulSoup لـ Go لمكتبات تجميع البيانات المماثلة في نظام Go.
استخدامات شائعة
استخراج البيانات لتطبيقات الذكاء الاصطناعي/LLM
يُعد Playwright ممتازًا لجمع البيانات التدريبية أو إنشاء قدرات البحث على الويب لنموذج الذكاء الاصطناعي. عند بناء خوادم MCP (بروتوكول سياق النموذج)، يمكن لـ Playwright التعامل مع مكون تجميع البيانات بينما يعالج LLM المحتوى المستخرج.
اختبارات تلقائية في CI/CD
دمج اختبارات Playwright في أنبوبك للتكامل المستمر:
# .github/workflows/playwright.yml
name: اختبارات Playwright
on:
push:
branches: [ main, master ]
pull_request:
branches: [ main, master ]
jobs:
test:
timeout-minutes: 60
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 18
- name: تثبيت الاعتمادات
run: npm ci
- name: تثبيت متصفحات Playwright
run: npx playwright install --with-deps
- name: تشغيل اختبارات Playwright
run: npx playwright test
- uses: actions/upload-artifact@v3
if: always()
with:
name: تقرير Playwright
path: تقرير Playwright/
retention-days: 30
مراقبة المواقع
مراقبة مواقعك في الإنتاج لمعرفة حالة التشغيل والوظائف:
import schedule
import time
def monitor_website():
with sync_playwright() as p:
try:
browser = p.chromium.launch()
page = browser.new_page()
page.goto('https://your-site.com', timeout=30000)
# التحقق من العناصر الأساسية
assert page.is_visible('.header')
assert page.is_visible('#main-content')
print("✓ الموقع بصحة جيدة")
except Exception as e:
print(f"✗ تم اكتشاف مشكلة في الموقع: {e}")
# إرسال تنبيه
finally:
browser.close()
# تكرار كل 5 دقائق
schedule.every(5).minutes.do(monitor_website)
while True:
schedule.run_pending()
time.sleep(1)
استكشاف المشكلات الشائعة
مشكلات تثبيت المتصفح
إذا فشل تحميل المتصفحات:
# تعيين موقع تنزيل مخصص
PLAYWRIGHT_BROWSERS_PATH=/custom/path playwright install
# مسح التخزين المؤقت وإعادة التثبيت
playwright uninstall
playwright install
أخطاء المهلة
زيادة المهلات لشبكات بطيئة أو صفحات معقدة:
page.goto('https://slow-site.com', timeout=60000) # 60 ثانية
page.wait_for_selector('.element', timeout=30000) # 30 ثانية
لم يتم العثور على المحدد
استخدم مدقق Playwright لتحديد المحددات الصحيحة:
PWDEBUG=1 pytest test_file.py
هذا يفتح المدقق حيث يمكنك التمرير فوق العناصر لرؤية محدداتها.
الخاتمة
يُعد Playwright أحدث تقنيات التحكم التلقائي للمتصفحات، الجمع بين الميزات القوية مع تجربة مطورة ممتازة. سواء كنت تبني أنبوبًا لجمع البيانات من الويب، أو تطبيق تغطية اختبارات شاملة، أو إنشاء عمليات تلقائية، يوفر Playwright الأدوات والموثوقية التي تحتاجها.
تستبعد آليات الانتظار التلقائية اختبارات غير موثوقة، ودعم المتصفحات عبر المتصفحات يضمن أن تطبيقاتك تعمل في كل مكان، وأدوات الاستكشاف القوية تجعل التصحيح سهلًا. مع استمرار تطور تطبيقات الويب، تصبح هيكلية Playwright الحديثة وتطويرها النشط خيارًا ممتازًا لأي احتياجات التحكم التلقائي في المتصفحات.
للمطورين في Python الذين يعملون على أنابيب البيانات أو مشاريع جمع البيانات، يتكامل Playwright بسلاسة مع مديري الحزم الحديثة ويؤدي بشكل ممتاز جنبًا إلى جنب مع pandas وrequests وأدوات تحليل البيانات الأخرى. القدرة على استخراج بيانات منظمة من المواقع الحديثة المعقدة تجعلها لا غنى عنها لتطبيقات الذكاء الاصطناعي، والمشاريع البحثية، والذكاء التجاري. عند الجمع مع أدوات تحويل HTML إلى Markdown ومعالجة المحتوى المناسبة، يصبح Playwright حلًا كاملًا لاستخراج، تحويل، واستخدام بيانات الويب بكمية كبيرة.
روابط مفيدة
- ورقة ملاحظات Python
- uv - مدير حزم Python، ومشاريع، وبيئات
- تحويل محتوى HTML إلى Markdown باستخدام LLM وOllama
- تحويل مستندات Word إلى Markdown: دليل شامل
- تحويل HTML إلى Markdown باستخدام Python: دليل شامل
- بناء خوادم MCP في Python: البحث على الويب وجمع البيانات
- بدائل BeautifulSoup لـ Go