البروكسيات الدوارة مع Playwright: دليل المطور الشامل

تعلم كيفية تنظيم التناوب المحترف في بلايرايت - المحترفون في كل منطقة، والسياقات الخفية، والتجهيز الجغرافي، والخردة المتزامنة، وأنماط تخطيط الإنتاج مع أمثلة رمزية.

البروكسيات الدوارة مع Playwright: دليل المطور الشامل
En este artículo

لماذا بلايرايت للمحترفين

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

عند الدمج مؤسسات الرعاية(بلايرايت) يصبح أحد أكثر الأدوات فعالية لجمع البيانات من المواقع الشبكية المحمية بشدة ويغطي هذا الدليل تشكيلة بديلة على كل مستوى: على نطاق المركب، وعلى مستوى كل منطقة، وعلى صفحة واحدة - مع رمز العمل الذي يمكنك نسخه مباشرة إلى مشاريعك.

هذا الدليلِ يَفترضُ بأنّك عِنْدَكَ a حساب ProxyHat. إذا كنت جديد على المحترفين، تبدأ ما هو الوكيل؟ ثم نستعرض أفضل محترفين لخردة الإنترنت لمحة عامة.

التركيب والإنشاء

Node.js (Primary)

# Install Playwright
npm init -y
npm install playwright
# Download browser binaries
npx playwright install chromium

Python

# Install Playwright for Python
pip install playwright
python -m playwright install chromium

Browser-Level Proxy Configuration

أبسط نهج يُحدّدُ a محترف في إطلاقِ بروزر. كل سياق و صفحة يرث هذا الوكيل تلقائياً

Node.js — Browser-Wide Proxy

const { chromium } = require('playwright');
(async () => {
  const browser = await chromium.launch({
    proxy: {
      server: 'http://gate.proxyhat.com:8080',
      username: 'USERNAME',
      password: 'PASSWORD',
    },
  });
  const page = await browser.newPage();
  await page.goto('https://httpbin.org/ip');
  console.log(await page.textContent('body'));
  await browser.close();
})();

Python - Browser-Wide Proxy

from playwright.sync_api import sync_playwright
with sync_playwright() as p:
    browser = p.chromium.launch(
        proxy={
            "server": "http://gate.proxyhat.com:8080",
            "username": "USERNAME",
            "password": "PASSWORD",
        }
    )
    page = browser.new_page()
    page.goto("https://httpbin.org/ip")
    print(page.text_content("body"))
    browser.close()

Per-Context Proxy Rotation

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

Node.js - Per-Context Rotation

const { chromium } = require('playwright');
const crypto = require('crypto');
async function createProxiedContext(browser) {
  const sessionId = crypto.randomBytes(4).toString('hex');
  const context = await browser.newContext({
    proxy: {
      server: 'http://gate.proxyhat.com:8080',
      username: `USERNAME-session-${sessionId}`,
      password: 'PASSWORD',
    },
  });
  return context;
}
(async () => {
  // Launch browser WITHOUT a proxy — set it per context
  const browser = await chromium.launch();
  const urls = [
    'https://example.com/page/1',
    'https://example.com/page/2',
    'https://example.com/page/3',
  ];
  for (const url of urls) {
    const context = await createProxiedContext(browser);
    const page = await context.newPage();
    try {
      await page.goto(url, { timeout: 30000 });
      const content = await page.content();
      console.log(`Fetched ${url} — ${content.length} chars`);
    } catch (err) {
      console.error(`Failed ${url}: ${err.message}`);
    } finally {
      await context.close(); // Releases the session
    }
  }
  await browser.close();
})();

Python - Per-Context Rotation

import uuid
from playwright.sync_api import sync_playwright
def create_proxied_context(browser):
    session_id = uuid.uuid4().hex[:8]
    context = browser.new_context(
        proxy={
            "server": "http://gate.proxyhat.com:8080",
            "username": f"USERNAME-session-{session_id}",
            "password": "PASSWORD",
        }
    )
    return context
with sync_playwright() as p:
    browser = p.chromium.launch()
    urls = [
        "https://example.com/page/1",
        "https://example.com/page/2",
        "https://example.com/page/3",
    ]
    for url in urls:
        context = create_proxied_context(browser)
        page = context.new_page()
        try:
            page.goto(url, timeout=30000)
            print(f"Fetched {url} — {len(page.content())} chars")
        except Exception as e:
            print(f"Failed {url}: {e}")
        finally:
            context.close()
    browser.close()

المناطق الجغرافية المستهدفة

عندما تخريد المحتوى المحلي، يمكنك الجمع بين الهدف الأرضي لـ(بروكسي هات) مع موقع (بلايرايت) وزمن الزمان لأقصى درجة من الموثوقية انظر جميع المواقع المتاحة لدينا المواقع.

const { chromium } = require('playwright');
const GEO_PROFILES = {
  us: { locale: 'en-US', timezone: 'America/New_York',  country: 'us' },
  de: { locale: 'de-DE', timezone: 'Europe/Berlin',     country: 'de' },
  jp: { locale: 'ja-JP', timezone: 'Asia/Tokyo',        country: 'jp' },
};
async function createGeoContext(browser, region) {
  const profile = GEO_PROFILES[region];
  return browser.newContext({
    proxy: {
      server: 'http://gate.proxyhat.com:8080',
      username: `USERNAME-country-${profile.country}`,
      password: 'PASSWORD',
    },
    locale: profile.locale,
    timezoneId: profile.timezone,
    geolocation: null,
  });
}
(async () => {
  const browser = await chromium.launch();
  for (const region of ['us', 'de', 'jp']) {
    const context = await createGeoContext(browser, region);
    const page = await context.newPage();
    await page.goto('https://example.com/pricing');
    console.log(`${region.toUpperCase()}: ${await page.title()}`);
    await context.close();
  }
  await browser.close();
})();

التلاعب بالعامل

سياقات (بلايرايت) خفيفة الوزن يمكنك أن تُدير سياقات متعددة بالتوازي، كل واحدة منها لها جلسة متتالية مختلفة، للزيادة الهائلة في الناتج.

const { chromium } = require('playwright');
const crypto = require('crypto');
const MAX_CONCURRENCY = 5;
async function scrapeUrl(browser, url) {
  const sessionId = crypto.randomBytes(4).toString('hex');
  const context = await browser.newContext({
    proxy: {
      server: 'http://gate.proxyhat.com:8080',
      username: `USERNAME-session-${sessionId}`,
      password: 'PASSWORD',
    },
  });
  const page = await context.newPage();
  try {
    await page.goto(url, { timeout: 30000, waitUntil: 'domcontentloaded' });
    const title = await page.title();
    return { url, title, success: true };
  } catch (err) {
    return { url, error: err.message, success: false };
  } finally {
    await context.close();
  }
}
async function scrapeAll(urls) {
  const browser = await chromium.launch();
  const results = [];
  // Process in batches of MAX_CONCURRENCY
  for (let i = 0; i < urls.length; i += MAX_CONCURRENCY) {
    const batch = urls.slice(i, i + MAX_CONCURRENCY);
    const batchResults = await Promise.all(
      batch.map(url => scrapeUrl(browser, url))
    );
    results.push(...batchResults);
    console.log(`Completed batch ${Math.floor(i / MAX_CONCURRENCY) + 1}`);
  }
  await browser.close();
  return results;
}
// Usage
const urls = Array.from({ length: 20 }, (_, i) =>
  `https://example.com/product/${i + 1}`
);
scrapeAll(urls).then(results => {
  const success = results.filter(r => r.success).length;
  console.log(`Success: ${success}/${results.length}`);
});

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

اتحاد الإنقاذ

مروجي بلايرايت المخادعين لديهم علامات آليّة قابلة للكشف هذه البيئات تقلل من بصماتك وتساعد على التجاوز نظم مضادة للمركبات.

Essential Stealth Settings

const { chromium } = require('playwright');
(async () => {
  const browser = await chromium.launch({
    args: [
      '--disable-blink-features=AutomationControlled',
      '--disable-features=IsolateOrigins,site-per-process',
    ],
  });
  const context = await browser.newContext({
    proxy: {
      server: 'http://gate.proxyhat.com:8080',
      username: 'USERNAME',
      password: 'PASSWORD',
    },
    userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36',
    viewport: { width: 1920, height: 1080 },
    locale: 'en-US',
    timezoneId: 'America/New_York',
    deviceScaleFactor: 1,
    hasTouch: false,
    isMobile: false,
    javaScriptEnabled: true,
  });
  // Remove automation markers
  await context.addInitScript(() => {
    // Override navigator.webdriver
    Object.defineProperty(navigator, 'webdriver', {
      get: () => undefined,
    });
    // Override navigator.plugins to look real
    Object.defineProperty(navigator, 'plugins', {
      get: () => [1, 2, 3, 4, 5],
    });
    // Override navigator.languages
    Object.defineProperty(navigator, 'languages', {
      get: () => ['en-US', 'en'],
    });
    // Override chrome.runtime to avoid detection
    window.chrome = { runtime: {} };
  });
  const page = await context.newPage();
  await page.goto('https://bot.sannysoft.com/');
  await page.screenshot({ path: 'stealth-test.png' });
  await browser.close();
})();

Python Stealth Configuration

from playwright.sync_api import sync_playwright
with sync_playwright() as p:
    browser = p.chromium.launch(
        args=[
            "--disable-blink-features=AutomationControlled",
        ]
    )
    context = browser.new_context(
        proxy={
            "server": "http://gate.proxyhat.com:8080",
            "username": "USERNAME",
            "password": "PASSWORD",
        },
        user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
                   "AppleWebKit/537.36 (KHTML, like Gecko) "
                   "Chrome/131.0.0.0 Safari/537.36",
        viewport={"width": 1920, "height": 1080},
        locale="en-US",
        timezone_id="America/New_York",
    )
    context.add_init_script("""
        Object.defineProperty(navigator, 'webdriver', {
            get: () => undefined,
        });
        window.chrome = { runtime: {} };
    """)
    page = context.new_page()
    page.goto("https://httpbin.org/headers")
    print(page.text_content("body"))
    browser.close()

Retry Logic with Proxy Rotation

ويضمن الجمع بين منطق إعادة التجريب والتناوب التلقائي العميل تلبية الطلبات المفقودة بمجموعة جديدة من شركاء التنفيذ والسياق.

const { chromium } = require('playwright');
const crypto = require('crypto');
async function fetchWithRetry(browser, url, maxRetries = 3) {
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
    const sessionId = crypto.randomBytes(4).toString('hex');
    const context = await browser.newContext({
      proxy: {
        server: 'http://gate.proxyhat.com:8080',
        username: `USERNAME-session-${sessionId}`,
        password: 'PASSWORD',
      },
    });
    const page = await context.newPage();
    try {
      const response = await page.goto(url, {
        timeout: 30000,
        waitUntil: 'domcontentloaded',
      });
      if (response && response.status() >= 400) {
        console.log(`Attempt ${attempt}: HTTP ${response.status()}, retrying...`);
        await context.close();
        continue;
      }
      const html = await page.content();
      await context.close();
      return html;
    } catch (err) {
      console.log(`Attempt ${attempt} failed: ${err.message}`);
      await context.close();
      if (attempt === maxRetries) {
        throw new Error(`All ${maxRetries} attempts failed for ${url}`);
      }
      // Exponential backoff
      await new Promise(r => setTimeout(r, 1000 * Math.pow(2, attempt - 1)));
    }
  }
}
(async () => {
  const browser = await chromium.launch();
  try {
    const html = await fetchWithRetry(browser, 'https://example.com/data');
    console.log(`Fetched ${html.length} chars`);
  } catch (err) {
    console.error(err.message);
  }
  await browser.close();
})();

SOCKS5 Proxy with Playwright

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

const { chromium } = require('playwright');
(async () => {
  const browser = await chromium.launch({
    proxy: {
      server: 'socks5://gate.proxyhat.com:1080',
      username: 'USERNAME',
      password: 'PASSWORD',
    },
  });
  const page = await browser.newPage();
  await page.goto('https://httpbin.org/ip');
  console.log(await page.textContent('body'));
  await browser.close();
})();

خط الإنتاج

وها هي عبارة عن خردة كاملة لقراءة الإنتاج تجمع بين جميع الأنماط المذكورة أعلاه - التناوب على أساس كل شبه جزيرة، والإطارات الخفية، ومنطق إعادة التجفيف، والتوافق، واستخراج البيانات المنظم.

const { chromium } = require('playwright');
const crypto = require('crypto');
const fs = require('fs');
class PlaywrightScraper {
  constructor({ concurrency = 3, maxRetries = 3 }) {
    this.concurrency = concurrency;
    this.maxRetries = maxRetries;
    this.browser = null;
    this.results = [];
    this.stats = { success: 0, failed: 0 };
  }
  async init() {
    this.browser = await chromium.launch({
      args: ['--disable-blink-features=AutomationControlled'],
    });
  }
  _createContext() {
    const sessionId = crypto.randomBytes(4).toString('hex');
    return this.browser.newContext({
      proxy: {
        server: 'http://gate.proxyhat.com:8080',
        username: `USERNAME-session-${sessionId}`,
        password: 'PASSWORD',
      },
      userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36',
      viewport: { width: 1920, height: 1080 },
      locale: 'en-US',
    });
  }
  async scrapePage(url) {
    for (let attempt = 1; attempt <= this.maxRetries; attempt++) {
      const context = await this._createContext();
      const page = await context.newPage();
      try {
        const response = await page.goto(url, {
          timeout: 30000,
          waitUntil: 'networkidle',
        });
        if (!response || response.status() >= 400) {
          await context.close();
          continue;
        }
        // Extract data — customize this for your target
        const data = await page.evaluate(() => ({
          title: document.title,
          text: document.body.innerText.substring(0, 500),
        }));
        await context.close();
        this.stats.success++;
        return { url, ...data, success: true };
      } catch (err) {
        await context.close();
        if (attempt === this.maxRetries) {
          this.stats.failed++;
          return { url, error: err.message, success: false };
        }
        await new Promise(r => setTimeout(r, 1000 * attempt));
      }
    }
  }
  async scrapeAll(urls) {
    await this.init();
    for (let i = 0; i < urls.length; i += this.concurrency) {
      const batch = urls.slice(i, i + this.concurrency);
      const batchResults = await Promise.all(
        batch.map(url => this.scrapePage(url))
      );
      this.results.push(...batchResults);
    }
    await this.browser.close();
    console.log(`Done: ${this.stats.success} OK, ${this.stats.failed} failed`);
    return this.results;
  }
}
// Usage
const scraper = new PlaywrightScraper({ concurrency: 5, maxRetries: 3 });
const urls = Array.from({ length: 50 }, (_, i) =>
  `https://example.com/item/${i + 1}`
);
scraper.scrapeAll(urls).then(results => {
  fs.writeFileSync('results.json', JSON.stringify(results, null, 2));
});

من أجل بناء طبقة متفجرة قابلة لإعادة الاستخدام بناء شركة بروسي ميدلوار- استكشاف Node SDK و Python SDK من أجل تبسيط الإدارة البديلة والتحقق تسعير ProxyHat للبدء

الأسئلة المتكررة

Preguntas frecuentes

Can Playwright use a different proxy for each page?

Playwright does not support per-page proxies directly, but you can achieve the same result by creating a new browser context for each proxy session. Each context is isolated with its own cookies, storage, and proxy configuration.

Is Playwright better than Puppeteer for proxy-based scraping?

Playwright offers several advantages: built-in proxy authentication support (no page.authenticate workaround), per-context proxies without relaunching the browser, and multi-browser support (Chromium, Firefox, WebKit). Puppeteer is Chromium-only and requires extra plugins for stealth.

How many concurrent Playwright contexts can I run?

Each context uses roughly 20-50 MB of memory. On a machine with 8 GB RAM, you can comfortably run 20-50 concurrent contexts. The practical limit depends on your target site response times and available bandwidth.

Does Playwright work with SOCKS5 proxies?

Yes. Set the proxy server to socks5://gate.proxyhat.com:1080 in the browser launch or context options. Playwright handles SOCKS5 authentication and connection natively.

How do I avoid detection when using Playwright with proxies?

Combine residential proxies with stealth settings: remove navigator.webdriver, set realistic viewport and user-agent, match locale and timezone to the proxy location, and add random delays between actions. Per-context rotation ensures each session has a fresh fingerprint.

¿Listo para empezar?

Proxies residenciales, ISP y móviles en más de 148 países. Creá una cuenta gratis.

Crear cuenta gratis
← Volver al Blog