احراز هویت پروکسی در Selenium و Playwright: هر روشی که واقعاً کار می‌کند (۲۰۲۶)

منتشر شده در 4 ژوئن 2026 · زمان مطالعه ≈ 10 دقیقه

این همان تله‌ای است که هر توسعه‌دهنده اتوماسیون مرورگر دقیقاً یک‌بار در آن می‌افتد: --proxy-server=http://user:pass@host:port را به فلگ‌های راه‌اندازی Chrome اضافه می‌کنید، مرورگر خوب بالا می‌آید، و بعد هر صفحه روی یک پاپ‌آپ احراز هویت که اسکریپتتان نه می‌بیند و نه می‌تواند کلیک کند، گیر می‌کند. Chrome بی‌سروصدا اطلاعات احراز هویت را از فلگ پروکسی حذف می‌کند. نه خطایی، نه خط لاگی، فقط یک دیالوگ مودال در مرورگری که هیچ‌کس تماشایش نمی‌کند.

این راهنما نقشه کامل روش‌های احراز هویت پروکسی است که واقعاً در Selenium و Playwright در سال ۲۰۲۶ کار می‌کنند — کدام را استفاده کنید، از کدام بپرهیزید، و کد دقیق هرکدام. (برای استراتژی انتخاب و چرخش پروکسی در این ابزارها، استفاده از پروکسی با Playwright و Puppeteer را ببینید — این مقاله صرفاً درباره عبور دادن اطلاعات احراز هویت است.)

چرا user:pass@host در مرورگرها شکست می‌خورد

کلاینت‌های HTTP خط فرمان، اطلاعات احراز هویت را از روی URL پروکسی پارس می‌کنند و به 407 Proxy Authentication Required پروکسی به‌صورت خودکار با یک هدر Proxy-Authorization پاسخ می‌دهند. Chromium این کار را نمی‌کند: --proxy-server فقط scheme://host:port را می‌پذیرد، و وقتی ۴۰۷ برمی‌گردد یک دیالوگ تعاملی نشان می‌دهد. در حالت headless حتی دیالوگی هم نیست — درخواست فقط شکست می‌خورد.

پس سؤال هیچ‌وقت این نیست که «چطور رمز را در URL بگذارم» — سؤال این است که «کدام لایه به‌جای من به ۴۰۷ پاسخ می‌دهد». چهار پاسخ کارا، بهترین اول.

روش ۱: احراز هویت بومی Playwright (اگر می‌توانید همین را استفاده کنید)

Playwright این مشکل را درست حل کرد: خودش از طریق CDP به چالش‌های احراز هویت پروکسی پاسخ می‌دهد. اطلاعات احراز هویت در آپشن‌های launch یا context می‌روند:

# Python
from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch(
        proxy={
            "server": "http://us.jibaoproxy.com:913",
            "username": "USERNAME-session-job1",
            "password": "PASSWORD",
        }
    )
// Node.js - و به‌ازای هر context، که قدرت اصلی همین‌جاست:
const browser = await chromium.launch({
  proxy: { server: 'per-context' }   // declare intent at launch
});
const ctx = await browser.newContext({
  proxy: {
    server: 'http://us.jibaoproxy.com:913',
    username: 'USERNAME-session-job2',
    password: 'PASSWORD',
  }
});

پروکسی به‌ازای هر context یعنی یک پروسه مرورگر می‌تواند N کانتکست را روی N تای sticky session متفاوت اجرا کند — شالوده هر راه‌اندازی جدی اسکرپینگ با Playwright. اگر روی Playwright هستید، کارتان تمام است؛ به بخش تأیید بروید. هر چیزی پایین‌تر از این به این خاطر وجود دارد که Selenium معادلی ندارد.

روش ۲: selenium-wire (Selenium، پایتون)

selenium-wire دور Selenium یک پروکسی MITM محلی می‌پیچد که احراز هویت بالادست را مدیریت می‌کند:

from seleniumwire import webdriver   # pip install selenium-wire

options = {
    "proxy": {
        "http":  "http://USERNAME:[email protected]:913",
        "https": "https://USERNAME:[email protected]:913",
    }
}
driver = webdriver.Chrome(seleniumwire_options=options)
driver.get("https://example.com")

هشدارهایی که باید پیش از production بدانید:

روش ۳: افزونه Chrome برای تزریق اطلاعات احراز هویت (Selenium، هر زبانی)

رویکرد کلاسیک: یک افزونه کوچک تولیدشده که پروکسی را ست می‌کند و از طریق chrome.webRequest.onAuthRequired به احراز هویت پاسخ می‌دهد. نه MITM ای، نه پروسه اضافی، در Selenium ساده کار می‌کند:

import zipfile, json

HOST, PORT = "us.jibaoproxy.com", 913
USER, PASS = "USERNAME-session-sel1", "PASSWORD"

manifest = {
    "version": "1.0.0", "manifest_version": 2, "name": "Proxy Auth",
    "permissions": ["proxy", "webRequest", "webRequestBlocking", ""],
    "background": {"scripts": ["background.js"]},
}
background = f"""
chrome.proxy.settings.set({{value: {{mode: "fixed_servers", rules: {{
  singleProxy: {{scheme: "http", host: "{HOST}", port: {PORT}}}
}}}}, scope: "regular"}}, () => {{}});
chrome.webRequest.onAuthRequired.addListener(
  () => ({{authCredentials: {{username: "{USER}", password: "{PASS}"}}}}),
  {{urls: [""]}}, ["blocking"]
);
"""

with zipfile.ZipFile("proxy_auth.zip", "w") as zp:
    zp.writestr("manifest.json", json.dumps(manifest))
    zp.writestr("background.js", background)

from selenium import webdriver
opts = webdriver.ChromeOptions()
opts.add_extension("proxy_auth.zip")
driver = webdriver.Chrome(options=opts)

دو نکته ظریف: افزونه‌ها در حالت headless کلاسیک بارگذاری نمی‌شوند — از --headless=new (Chrome 109+) استفاده کنید یا headed اجرا کنید؛ و اسکریپت‌های background مربوط به Manifest V2 هنوز برای افزونه‌های اتوماسیون sideload شده کار می‌کنند اما حواستان به جدول زمانی منسوخ شدن MV2 در Chrome باشد — معادل MV3 به یک service worker و همان listener مربوط به onAuthRequired نیاز دارد.

روش ۴: Forwarder محلی (راه‌حل جایگزین جهانی)

یک پروکسی محلی کوچک اجرا کنید که اطلاعات احراز هویت را نگه دارد؛ مرورگر را بدون هیچ احراز هویتی به localhost اشاره دهید. با هر مرورگر، هر درایور، هر زبان، headless یا غیر آن کار می‌کند:

# با استفاده از pproxy (pip install pproxy) - ترمینال ۱:
pproxy -l http://127.0.0.1:8899 \
       -r "http://USERNAME:[email protected]:913"

# اسکریپت شما - ترمینال ۲: Selenium ساده، بدون نیاز به احراز هویت
opts = webdriver.ChromeOptions()
opts.add_argument("--proxy-server=http://127.0.0.1:8899")
driver = webdriver.Chrome(options=opts)

این تمیزترین پاسخ برای Firefox/geckodriver هم هست (جایی که ترفند افزونه کاربرد ندارد) و برای محیط‌های خاص مثل تست اپلیکیشن Electron. هزینه‌اش: یک قطعه متحرک بیشتر برای نظارت، و مسیریابی به‌ازای هر context به یک پورت forwarder به‌ازای هر session نیاز دارد.

مقایسه روش‌ها

روشکار می‌کند درHeadlesssession به‌ازای هر contextحکم production
بومی PlaywrightPlaywrightبلهبلهانتخاب پیش‌فرض
selenium-wireSelenium (پایتون)بلهبه‌ازای هر driverدر مقیاس متوسط خوب است
افزونه احراز هویتSelenium (هر زبان)فقط --headless=newبه‌ازای هر driverمحکم، حواستان به MV3
forwarder محلیهمه چیزبلهیک پورت به‌ازای هر sessionجایگزین جهانی

تأیید کنید که واقعاً کار کرده

بازگشت بی‌سروصدا به IP واقعی شما همان حالت شکستی است که حساب‌ها را بن می‌کند. در ابتدای هر اجرا IP خروجی را assert کنید:

ip = driver.execute_script(
    "return fetch('https://api.ipify.org').then(r => r.text())"
) if hasattr(driver, 'execute_script') else page.evaluate(
    "fetch('https://api.ipify.org').then(r => r.text())"
)
assert ip != MY_REAL_IP, "Proxy not applied - aborting before we leak"
ابزار رایگان · بدون ثبت‌نام

مرورگر خودکارتان را با چشم بررسی کنید

مرورگر Selenium/Playwright خود را به صفحه What Is My IP ما هدایت کنید: IP خروجی، موقعیت جغرافیایی، نوع ASN و پرچم‌های proxy/VPN را در یک نما نشان می‌دهد — تأیید فوری اینکه لایه احراز هویت کار کرده و IP مسکونی است.

چکر IP را باز کن →

روی یک پروکسی «مسکونی» یک ASN دیتاسنتر می‌بینید؟ به استخری بروید که واقعاً مسکونی است — ۵ دلار اعتبار رایگان →

مرجع سریع عیب‌یابی

جمع‌بندی

مرورگرها URL پروکسی به شکل user:pass@ را نمی‌خوانند — چیزی باید به‌جای آن‌ها به ۴۰۷ پاسخ دهد. در Playwright آن چیز توکار است؛ در Selenium آن چیز selenium-wire، یک افزونه احراز هویت تولیدشده، یا یک forwarder محلی است. بر اساس استک خودتان از جدول مقایسه انتخاب کنید، سپس در هر اجرا IP خروجی را assert کنید تا یک شکست احراز هویت بی‌سروصدا هرگز نتواند وسط کرال آدرس واقعی شما را لو دهد.

امشب هر چهار روش را تست کنید

۵ دلار اعتبار مسکونی رایگان — یک گیت‌وی، sticky یا چرخشی، HTTP و SOCKS5.

شروع تست رایگان

برای همه محصولات IP · هزاران نود همیشه در دسترس

همین حالا ثبت‌نام کنید و تا ۱۰۰٪ کش‌بک شارژ بگیرید

کاربران جدید با ثبت‌نام 500MB هدیه می‌گیرند، به‌علاوه بونوس اولین شارژ. پیشنهاد محدود.