یہ وہ پھندا ہے جس میں ہر browser-automation ڈویلپر ٹھیک ایک بار ضرور پھنستا ہے: آپ Chrome کے launch flags میں --proxy-server=http://user:pass@host:port شامل کرتے ہیں، browser ٹھیک شروع ہو جاتا ہے، اور پھر ہر page ایک authentication popup پر اٹک جاتا ہے جسے آپ کا script نہ دیکھ سکتا ہے نہ کلک کر سکتا ہے۔ Chrome خاموشی سے proxy flag سے credentials نکال پھینکتا ہے۔ نہ کوئی error، نہ کوئی log لائن، بس ایک ایسے browser میں modal dialog جسے کوئی نہیں دیکھ رہا۔
یہ گائیڈ ان proxy authentication طریقوں کا مکمل نقشہ ہے جو 2026 میں Selenium اور Playwright میں واقعی کام کرتے ہیں — کون سا استعمال کریں، کس سے بچیں، اور ہر ایک کے لیے بالکل درست code۔ (ان ٹولز میں proxy کے انتخاب اور rotation کی حکمتِ عملی کے لیے دیکھیں Playwright اور Puppeteer کے ساتھ Proxies کا استعمال — یہ مضمون خالصتاً credentials کو گزارنے کے بارے میں ہے۔)
Command-line HTTP clients proxy URLs سے credentials نکال لیتے ہیں اور proxy کے 407 Proxy Authentication Required کا جواب خودکار طور پر Proxy-Authorization header سے دے دیتے ہیں۔ Chromium ایسا نہیں کرتا: --proxy-server صرف scheme://host:port قبول کرتا ہے، اور جب 407 واپس آتا ہے تو یہ ایک interactive dialog دکھاتا ہے۔ headless mode میں تو dialog بھی نہیں ہوتا — request بس ناکام ہو جاتی ہے۔
چنانچہ سوال کبھی یہ نہیں کہ "میں password کو URL میں کیسے ڈالوں" — سوال یہ ہے کہ "میرے لیے 407 کا جواب کون سی layer دیتی ہے"۔ چار کام کرنے والے جواب، بہترین پہلے۔
Playwright نے یہ مسئلہ صحیح طریقے سے حل کیا: یہ proxy auth challenges کا جواب CDP کے ذریعے خود دیتا ہے۔ Credentials launch یا context options میں جاتے ہیں:
# 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 - and per-context, which is where it gets powerful:
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',
}
});
Per-context proxies کا مطلب ہے کہ ایک ہی browser process مختلف sticky sessions پر N مختلف contexts چلا سکتا ہے — یہی ہر سنجیدہ Playwright scraping setup کی بنیاد ہے۔ اگر آپ Playwright پر ہیں، تو آپ کا کام ہو گیا؛ تصدیق والے حصے پر چھلانگ لگا دیں۔ نیچے کی ہر چیز اس لیے موجود ہے کیونکہ Selenium کے پاس اس کا کوئی مساوی نہیں۔
selenium-wire Selenium کو ایک local MITM proxy میں لپیٹ دیتا ہے جو upstream authentication سنبھالتا ہے:
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 سے پہلے جان لینے والی احتیاطیں:
کلاسک طریقہ: ایک چھوٹا generated extension جو proxy سیٹ کرتا ہے اور chrome.webRequest.onAuthRequired کے ذریعے auth کا جواب دیتا ہے۔ نہ MITM، نہ کوئی اضافی process، سادہ 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)
دو پیچیدگیاں: extensions کلاسک headless mode میں load نہیں ہوتیں — --headless=new (Chrome 109+) استعمال کریں یا headed چلائیں؛ اور Manifest V2 background scripts sideloaded automation extensions کے لیے اب بھی کام کرتی ہیں مگر Chrome کی MV2 deprecation timeline پر نظر رکھیں — MV3 مساوی کے لیے ایک service worker اور وہی onAuthRequired listener درکار ہوتا ہے۔
ایک چھوٹا local proxy چلائیں جو credentials رکھتا ہو؛ browser کا رخ localhost کی طرف کریں بغیر کسی auth کے۔ ہر browser، ہر driver، ہر زبان، headless ہو یا نہ ہو، سب کے ساتھ کام کرتا ہے:
# Using pproxy (pip install pproxy) - terminal 1:
pproxy -l http://127.0.0.1:8899 \
-r "http://USERNAME:[email protected]:913"
# Your script - terminal 2: plain Selenium, no auth needed
opts = webdriver.ChromeOptions()
opts.add_argument("--proxy-server=http://127.0.0.1:8899")
driver = webdriver.Chrome(options=opts)
یہ Firefox/geckodriver کے لیے بھی سب سے صاف جواب ہے (جہاں extension والی ترکیب لاگو نہیں ہوتی) اور Electron app testing جیسے غیر معمولی ماحول کے لیے بھی۔ قیمت: نگرانی کے لیے ایک اور چلتا پرزہ، اور per-context routing کے لیے فی session ایک forwarder port درکار ہوتا ہے۔
| طریقہ | کس میں کام کرتا ہے | Headless | Per-context sessions | Production فیصلہ |
|---|---|---|---|---|
| Playwright native | Playwright | ہاں | ہاں | طے شدہ انتخاب |
| selenium-wire | Selenium (Py) | ہاں | Per-driver | معتدل پیمانے پر ٹھیک |
| Auth extension | Selenium (کوئی بھی زبان) | صرف --headless=new | Per-driver | مضبوط، MV3 پر نظر رکھیں |
| Local forwarder | ہر چیز | ہاں | فی session ایک port | آفاقی fallback |
آپ کے اصلی IP پر خاموش fallback وہی failure mode ہے جو accounts کو ban کراتا ہے۔ ہر run کے آغاز پر exit IP کی تصدیق کریں:
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"
--proxy-server میں بھیجے؛ Chrome نے انہیں گرا دیا۔ چاروں میں سے کوئی ایک طریقہ استعمال کریں۔ERR_PROXY_CONNECTION_FAILED — host/port غلط ہے یا protocol میل نہیں کھاتا۔ پہلے وہی لائن curl -x سے test کریں؛ اگر curl کام کرے، تو مسئلہ آپ کی browser wiring میں ہے۔--headless=new پر منتقل ہوں۔Browsers user:pass@ proxy URLs نہیں پڑھتے — ان کے لیے کسی کو 407 کا جواب دینا ہوتا ہے۔ Playwright میں وہ کوئی built-in ہوتا ہے؛ Selenium میں وہ selenium-wire، ایک generated auth extension، یا ایک local forwarder ہے۔ موازنے کی جدول سے اپنے stack کے مطابق چنیں، پھر ہر run پر exit IP کی تصدیق کریں تاکہ کوئی خاموش auth failure crawl کے بیچ آپ کا اصلی پتہ کبھی leak نہ کر سکے۔
500MB مفت رہائشی ٹریفک — ایک gateway، sticky یا rotating، HTTP اور SOCKS5۔
مفت ٹرائل شروع کریںنئے صارفین کو سائن اپ پر 500MB ملتے ہیں، اس کے علاوہ پہلے ری چارج پر بونس۔ پیشکش محدود وقت کے لیے ہے۔