بازگشت به وبلاگ

تنظیم پروکسی در Playwright برای تست بدون سر و صدا و پارسینگ: راهنمای کامل

نحوه اتصال صحیح پروکسی در Playwright برای تست بدون سر و صدا و پارس کردن را بررسی می‌کنیم - با مثال‌های کد، چرخش IP و دور زدن حفاظت ضد ربات.

📅۱۸ اردیبهشت ۱۴۰۵
```html

Playwright — یکی از قدرتمندترین ابزارها برای اتوماسیون مرورگر، تست‌های بدون سر و پارس کردن داده‌ها است. اما بدون پروکسی به درستی تنظیم شده، اسکریپت شما به سرعت از طرف IP مسدود خواهد شد: وب‌سایت‌ها یاد گرفته‌اند که درخواست‌های اتوماسیون شده را شناسایی کرده و آنها را مسدود کنند. در این راهنما تمام روش‌های اتصال پروکسی در Playwright را بررسی خواهیم کرد — از تنظیمات پایه تا چرخش IP و دور زدن Cloudflare.

چرا پروکسی در Playwright و چه زمانی نمی‌توان بدون آن کار کرد

Playwright یک مرورگر واقعی (Chromium، Firefox یا WebKit) را در پس‌زمینه اجرا می‌کند — این همان حالت بدون سر است. از نظر وب‌سایت، شما به عنوان یک کاربر عادی به نظر می‌رسید، اما فقط تا زمانی که از یک IP صدها درخواست در ساعت ارسال شود، الگوریتم‌های حفاظتی به سرعت واکنش نشان می‌دهند: CAPTCHA، مسدودیت موقت، مسدودیت کامل.

در اینجا سناریوهای خاصی وجود دارد که در آن پروکسی الزامی است:

  • پارس کردن بازارهای آنلاین — Wildberries، Ozon، Avito، Yandex.Market بعد از 50–100 درخواست از یک IP، اسکریپت‌ها را مسدود می‌کنند.
  • نظارت بر قیمت‌های رقباء — اگر هر 15 دقیقه بررسی کنید، بدون تغییر IP در عرض چند ساعت مسدود خواهید شد.
  • تست جغرافیایی — باید بررسی کنید که وب‌سایت برای کاربران از آلمان، ایالات متحده یا قزاقستان چگونه به نظر می‌رسد.
  • پر کردن فرم‌ها و ثبت‌نام حساب‌ها — پلتفرم‌ها حساب‌ها را به IP متصل می‌کنند و ثبت‌نام انبوه را مسدود می‌کنند.
  • نظارت بر SEO — جمع‌آوری موقعیت‌ها از Google و Yandex نیاز به تغییر مداوم IP دارد، در غیر این صورت موتور جستجو CAPTCHA را نشان می‌دهد.
  • تست ویژگی‌های A/B — برخی ویژگی‌ها فقط برای کاربران از کشورهای خاص یا مناطق خاص در دسترس هستند.

مهم است که درک کنید: Playwright به خودی خود شما را ناشناس نمی‌کند. بدون پروکسی، تمام درخواست‌ها از آدرس IP واقعی شما می‌آید. افزودن پروکسی، اولین و مهم‌ترین گام برای کارکرد پایدار هر اسکریپت اتوماسیون شده است.

💡 مهم است بدانید

Playwright از پروکسی در سطح کل مرورگر، زمینه جداگانه (BrowserContext) و حتی صفحه جداگانه پشتیبانی می‌کند. این انعطاف‌پذیری را فراهم می‌کند: صفحات مختلف می‌توانند به طور همزمان از IP‌های مختلف استفاده کنند.

کدام نوع پروکسی برای اتوماسیون بدون سر انتخاب کنیم

همه پروکسی‌ها به یک اندازه برای Playwright مناسب نیستند. انتخاب بستگی به وظیفه دارد: شما چه چیزی را پارس می‌کنید، حفاظت وب‌سایت چقدر تهاجمی است و چه حجم درخواست‌هایی را برنامه‌ریزی کرده‌اید.

نوع پروکسی سطح اعتماد سرعت مناسب برای
داده‌مرکز پایین بسیار بالا پارس کردن بدون حفاظت سخت، تست
رزیندنت بالا متوسط وب‌سایت‌های با Cloudflare، بازارهای آنلاین، شبکه‌های اجتماعی
موبایل حداکثری متوسط Facebook، TikTok، Instagram، ضد ربات‌های سخت
SOCKS5 بستگی به منبع دارد بالا پروتکل عمومی، توسط Playwright پشتیبانی می‌شود

برای اکثر وظایف پارس کردن انتخاب بهینه، پروکسی‌های رزیندنت با چرخش هستند. آنها IP‌های واقعی کاربران خانگی دارند، بنابراین وب‌سایت‌ها آنها را به عنوان داده‌مرکز شناسایی نمی‌کنند و به طور خودکار مسدود نمی‌شوند. برای وب‌سایت‌های با حفاظت تهاجمی (مدیریت ربات Cloudflare، Akamai) بهتر است از پروکسی‌های موبایل استفاده کنید — IP‌های آنها متعلق به اپراتورهای تلفن همراه است که حداکثر اعتماد را ایجاد می‌کند.

Playwright از پروتکل‌های http، https و socks5 پشتیبانی می‌کند. مهم است: SOCKS5 در برخی نسخه‌ها از احراز هویت از طریق username:password به طور مستقیم پشتیبانی نمی‌کند — در این مورد بیشتر در بخش خطاها توضیح داده شده است.

تنظیمات پایه پروکسی در Playwright (JavaScript و Python)

Playwright به شما اجازه می‌دهد تا پروکسی را هنگام راه‌اندازی مرورگر از طریق پارامتر proxy تعیین کنید. این ساده‌ترین روش است — تمام درخواست‌های مرورگر از طریق سرور پروکسی مشخص شده خواهد رفت.

JavaScript / Node.js

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

(async () => {
  const browser = await chromium.launch({
    proxy: {
      server: 'http://proxy.example.com:8080'
    }
  });

  const page = await browser.newPage();
  await page.goto('https://httpbin.org/ip');
  
  const content = await page.textContent('body');
  console.log(content); // IP سرور پروکسی را نشان می‌دهد

  await browser.close();
})();

Python

from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch(
        proxy={
            "server": "http://proxy.example.com:8080"
        }
    )
    
    page = browser.new_page()
    page.goto("https://httpbin.org/ip")
    
    print(page.text_content("body"))  # IP پروکسی را نشان می‌دهد
    
    browser.close()

برای SOCKS5 فقط آدرس سرور را تغییر دهید:

# Python — پروکسی SOCKS5
browser = p.chromium.launch(
    proxy={
        "server": "socks5://proxy.example.com:1080"
    }
)

برای بررسی سریع اینکه پروکسی کار می‌کند، https://httpbin.org/ip یا https://api.ipify.org را باز کنید — در پاسخ باید IP سرور پروکسی باشد، نه IP واقعی شما.

پروکسی با احراز هویت با نام کاربری و رمز عبور

بیشتر ارائه‌دهندگان پروکسی تجاری از احراز هویت با نام کاربری و رمز عبور استفاده می‌کنند — این یک عمل استاندارد است. Playwright این را از طریق فیلدهای username و password در شی پروکسی پشتیبانی می‌کند.

JavaScript

const browser = await chromium.launch({
  proxy: {
    server: 'http://gate.proxyprovider.com:7777',
    username: 'your_login',
    password: 'your_password'
  }
});

Python

browser = p.chromium.launch(
    proxy={
        "server": "http://gate.proxyprovider.com:7777",
        "username": "your_login",
        "password": "your_password"
    }
)

همچنین می‌توانید نام کاربری و رمز عبور را مستقیماً در URL پروکسی سرور ارسال کنید — این راحت است اگر شما رشته را به صورت دینامیکی تشکیل می‌دهید:

# احراز هویت در URL (Python)
proxy_url = f"http://{login}:{password}@gate.proxyprovider.com:7777"

browser = p.chromium.launch(
    proxy={"server": proxy_url}
)

⚠️ توجه

نام کاربری و رمز عبور پروکسی را مستقیماً در کد ذخیره نکنید! از متغیرهای محیطی (os.environ در Python یا process.env در Node.js) یا فایل .env با کتابخانه dotenv استفاده کنید.

ذخیره‌سازی امن از طریق .env (Python)

import os
from dotenv import load_dotenv
from playwright.sync_api import sync_playwright

load_dotenv()

PROXY_SERVER   = os.getenv("PROXY_SERVER")
PROXY_LOGIN    = os.getenv("PROXY_LOGIN")
PROXY_PASSWORD = os.getenv("PROXY_PASSWORD")

with sync_playwright() as p:
    browser = p.chromium.launch(
        proxy={
            "server":   PROXY_SERVER,
            "username": PROXY_LOGIN,
            "password": PROXY_PASSWORD
        }
    )
    # ...

چرخش پروکسی: تغییر IP برای هر درخواست

یک پروکسی در حجم بالای درخواست‌ها شما را از مسدودیت نجات نخواهد داد. برای پارس کردن جدی نیاز به چرخش IP است — تغییر خودکار پروکسی سرور در فواصل معین یا برای هر درخواست جدید.

دو رویکرد برای چرخش در Playwright وجود دارد:

رویکرد 1: نقطه پایانی پروکسی چرخشی

بیشتر ارائه‌دهندگان پروکسی‌های رزیندنت یک آدرس gateway واحد ارائه می‌دهند که به طور خودکار IP را در هر اتصال تغییر می‌دهد. نیازی به نوشتن منطق چرخش نیست — این در سمت ارائه‌دهنده گنجانده شده است.

# یک نقطه پایانی — IP جدید در هر اتصال مرورگر
browser = p.chromium.launch(
    proxy={
        "server":   "http://rotating.proxyprovider.com:8888",
        "username": "your_login",
        "password": "your_password"
    }
)

رویکرد 2: چرخش دستی از طریق لیست پروکسی

اگر لیستی از پروکسی‌های ایستا دارید، می‌توانید چرخش را به صورت دستی پیاده‌سازی کنید — با ایجاد یک مرورگر جدید یا زمینه برای هر تکرار:

import random
from playwright.sync_api import sync_playwright

PROXY_LIST = [
    {"server": "http://proxy1.example.com:8080", "username": "user", "password": "pass"},
    {"server": "http://proxy2.example.com:8080", "username": "user", "password": "pass"},
    {"server": "http://proxy3.example.com:8080", "username": "user", "password": "pass"},
]

URLS_TO_SCRAPE = [
    "https://example.com/page1",
    "https://example.com/page2",
    "https://example.com/page3",
]

with sync_playwright() as p:
    for url in URLS_TO_SCRAPE:
        proxy = random.choice(PROXY_LIST)  # پروکسی تصادفی
        
        browser = p.chromium.launch(proxy=proxy)
        page = browser.new_page()
        
        page.goto(url)
        # ... پارس کردن داده‌ها ...
        
        browser.close()  # مرورگر را می‌بندیم، IP را تغییر می‌دهیم

رویکرد 3: چرخش از طریق BrowserContext (بدون راه‌اندازی مجدد مرورگر)

with sync_playwright() as p:
    browser = p.chromium.launch()  # مرورگر بدون پروکسی
    
    for i, url in enumerate(URLS_TO_SCRAPE):
        proxy = PROXY_LIST[i % len(PROXY_LIST)]  # به صورت دورانی
        
        # زمینه جدید با پروکسی جدید — سریع‌تر از راه‌اندازی مجدد مرورگر
        context = browser.new_context(proxy=proxy)
        page = context.new_page()
        
        page.goto(url)
        # ... پارس کردن ...
        
        context.close()  # زمینه را می‌بندیم، نه مرورگر
    
    browser.close()

رویکرد سوم — برای پارس کردن انبوه، بهترین عملکرد را دارد. راه‌اندازی مجدد مرورگر 2–4 ثانیه طول می‌کشد، در حالی که ایجاد زمینه جدید کمتر از 100 میلی‌ثانیه زمان می‌برد.

پروکسی در سطح زمینه و صفحه

Playwright از معماری انعطاف‌پذیری پشتیبانی می‌کند: یک مرورگر می‌تواند چندین زمینه ایزوله داشته باشد، هر کدام با پروکسی خود. این امکان را می‌دهد که به طور همزمان با چندین IP در یک فرآیند کار کنید.

چندین زمینه با پروکسی‌های مختلف (پارس کردن موازی)

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

(async () => {
  const browser = await chromium.launch();

  // زمینه 1 — پروکسی از آلمان
  const context_de = await browser.newContext({
    proxy: {
      server: 'http://de-proxy.example.com:8080',
      username: 'user',
      password: 'pass'
    }
  });

  // زمینه 2 — پروکسی از ایالات متحده
  const context_us = await browser.newContext({
    proxy: {
      server: 'http://us-proxy.example.com:8080',
      username: 'user',
      password: 'pass'
    }
  });

  const page_de = await context_de.newPage();
  const page_us = await context_us.newPage();

  // اجرای موازی
  await Promise.all([
    page_de.goto('https://example.com'),
    page_us.goto('https://example.com')
  ]);

  // هر دو صفحه IP‌های متفاوتی را مشاهده می‌کنند
  console.log('DE IP:', await page_de.textContent('body'));
  console.log('US IP:', await page_us.textContent('body'));

  await browser.close();
})();

این رویکرد برای تست جغرافیایی ایده‌آل است: شما به طور همزمان بررسی می‌کنید که وب‌سایت برای کاربران از کشورهای مختلف چگونه نمایش داده می‌شود، بدون اینکه چندین نمونه از مرورگر را راه‌اندازی کنید.

💡 نکته‌ای برای عملکرد

برای حداکثر موازی بودن از asyncio در Python یا Promise.all در Node.js استفاده کنید. یک مرورگر می‌تواند 10–20 زمینه موازی را بدون بارگذاری قابل توجهی روی حافظه نگه دارد.

دور زدن حفاظت ضد ربات: Cloudflare، Akamai، DataDome

پروکسی فقط بخشی از راه‌حل است. سیستم‌های ضد ربات مدرن ده‌ها سیگنال را به طور همزمان تحلیل می‌کنند: اثر انگشت مرورگر، رفتار ماوس، سرعت پر کردن فرم‌ها، هدرهای HTTP و بسیاری دیگر. حتی با پروکسی خوب، اگر این عوامل را در نظر نگیرید، ممکن است مسدود شوید.

1. پنهان‌سازی حالت بدون سر

Playwright در حالت بدون سر دارای نشانه‌های خاصی است که به راحتی شناسایی می‌شوند: مقادیر خاص navigator.webdriver، عدم وجود پلاگین‌ها، اندازه‌های غیر استاندارد صفحه نمایش. از کتابخانه playwright-stealth برای پنهان‌سازی استفاده کنید:

# Python: نصب
# pip install playwright-stealth

from playwright.sync_api import sync_playwright
from playwright_stealth import stealth_sync

with sync_playwright() as p:
    browser = p.chromium.launch(
        proxy={
            "server":   "http://residential.proxyprovider.com:8888",
            "username": "user",
            "password": "pass"
        }
    )
    page = browser.new_page()
    stealth_sync(page)  # اعمال پنهان‌سازی
    
    page.goto("https://bot.sannysoft.com")  # تست شناسایی ربات
    browser.close()

2. User-Agent و viewport واقعی

context = browser.new_context(
    proxy={
        "server":   "http://proxy.example.com:8080",
        "username": "user",
        "password": "pass"
    },
    user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
    viewport={"width": 1920, "height": 1080},
    locale="fa-IR",
    timezone_id="Asia/Tehran"  # باید با جغرافیای پروکسی مطابقت داشته باشد!
)

3. شبیه‌سازی رفتار انسانی

import time
import random

# تأخیرهای تصادفی بین اقدامات
def human_delay(min_ms=500, max_ms=2000):
    time.sleep(random.randint(min_ms, max_ms) / 1000)

page.goto("https://example.com")
human_delay()

# اسکرول نرم به جای فوری
page.evaluate("window.scrollBy({top: 500, behavior: 'smooth'})")
human_delay(300, 800)

# حرکت ماوس قبل از کلیک
page.mouse.move(100, 200)
human_delay(100, 300)
page.mouse.move(300, 400)
human_delay(100, 200)
page.click("button#submit")

4. مطابقت زمان‌سنجی با جغرافیای پروکسی

این اغلب نادیده گرفته می‌شود، اما سیستم‌های ضد ربات مطابقت را بررسی می‌کنند: اگر پروکسی شما از تهران باشد، اما مرورگر زمان‌سنجی UTC-8 (لس آنجلس) را نشان دهد — این یک پرچم قرمز است. همیشه timezone_id را مطابق با جغرافیای پروکسی استفاده شده تنظیم کنید.

خطاهای رایج و نحوه رفع آنها

هنگام کار با پروکسی در Playwright، توسعه‌دهندگان به طور منظم با مشکلات مشابهی مواجه می‌شوند. هر یک را با راه‌حل خاص خود بررسی خواهیم کرد.

خطا 1: ERR_PROXY_CONNECTION_FAILED

دلیل: آدرس یا پورت پروکسی نادرست، پروکسی در دسترس نیست، اعتبارنامه‌های نادرست.
راه‌حل: قبل از راه‌اندازی Playwright، دسترسی پروکسی را از طریق curl بررسی کنید:

# بررسی پروکسی از طریق curl
curl -x http://user:[email protected]:8080 https://api.ipify.org

خطا 2: SOCKS5 احراز هویت را نمی‌پذیرد

دلیل: Playwright (Chromium) پشتیبانی محدودی از SOCKS5 با احراز هویت از طریق username/password دارد.
راه‌حل: از پروکسی HTTP با احراز هویت استفاده کنید یا یک تونل SOCKS5 محلی را از طریق ssh -D بدون رمز عبور تنظیم کنید.

خطا 3: پروکسی کار می‌کند، اما وب‌سایت هنوز هم مسدود می‌کند

دلیل: از پروکسی‌های داده‌مرکز استفاده می‌شود که در لیست سیاه هستند؛ حالت بدون سر پنهان نشده است؛ فرکانس درخواست‌ها بسیار بالا است.
راه‌حل: به پروکسی‌های رزیندنت یا موبایل بروید، playwright-stealth را اضافه کنید، تأخیرها بین درخواست‌ها را افزایش دهید.

خطا 4: نشت IP واقعی (DNS leak)

دلیل: درخواست‌های DNS ممکن است از پروکسی عبور کنند.
راه‌حل: Playwright به طور پیش‌فرض DNS را از طریق پروکسی هنگام استفاده از پروکسی HTTP هدایت می‌کند. اما برای بررسی از https://dnsleaktest.com در مرورگر بدون سر استفاده کنید.

خطا 5: عملکرد کند با پروکسی

دلیل: پروکسی‌های رزیندنت کندتر از داده‌مرکزی‌ها هستند؛ فاصله زیاد تا سرور پروکسی.
راه‌حل: پروکسی‌هایی را در مکان‌های جغرافیایی نزدیک انتخاب کنید. برای وظایفی که نیاز به ناشناسی سخت ندارند، از پروکسی‌های داده‌مرکزی استفاده کنید — آنها به طور قابل توجهی سریع‌تر هستند.

خطا راه‌حل سریع
ERR_PROXY_CONNECTION_FAILED بررسی curl، نام کاربری/رمز عبور، دسترسی به پورت
407 Proxy Auth Required اضافه کردن نام کاربری و رمز عبور به تنظیمات پروکسی
وب‌سایت CAPTCHA را نشان می‌دهد تغییر نوع پروکسی به رزیندنت، اضافه کردن stealth
IP در هنگام چرخش تغییر نمی‌کند بستن زمینه/مرورگر بین درخواست‌ها
تایم‌اوت اتصال افزایش timeout در goto()، انتخاب پروکسی نزدیک‌تر

نتیجه‌گیری و توصیه‌ها

تنظیم پروکسی در Playwright یک کار یک‌باره نیست، بلکه بخشی از معماری ابزار اتوماسیون شماست. نوع پروکسی به درستی انتخاب شده، چرخش IP هوشمند و پنهان‌سازی حالت بدون سر به طور مشترک کارکرد پایداری حتی در وب‌سایت‌های با حفاظت ضد ربات تهاجمی را فراهم می‌کنند.

بیایید خلاصه‌ای از انتخاب نوع پروکسی برای وظایف خاص ارائه دهیم:

  • پارس کردن داده‌های عمومی بدون حفاظت سخت — پروکسی‌های سریع داده‌مرکز مناسب هستند.
  • بازارهای آنلاین (Wildberries، Ozon)، تجمیع‌کننده‌های خبری — پروکسی‌های رزیندنت با چرخش نیاز است.
  • شبکه‌های اجتماعی (Instagram، Facebook، TikTok) و وب‌سایت‌های با Cloudflare — فقط پروکسی‌های موبایل یا رزیندنت.
  • تست جغرافیایی — هر نوع پروکسی در کشور مورد نظر، نکته اصلی — مطابقت زمان‌سنجی.
  • پارس کردن انبوه با فرکانس بالا — پروکسی‌های رزیندنت چرخشی با نقطه پایانی gateway.

اگر شما در حال ساخت یک سیستم پارس کردن یا تست اتوماسیون بر روی Playwright هستید و به کارکرد پایدار بدون مسدودیت نیاز دارید، توصیه می‌کنیم پروکسی‌های رزیندنت را در نظر بگیرید — آنها سطح بالایی از اعتماد را از طرف وب‌سایت‌ها فراهم می‌کنند و از چرخش IP از طریق یک نقطه پایانی واحد پشتیبانی می‌کنند، که ادغام با Playwright را به چند خط کد ساده می‌کند.

```