إليك الفخ الذي يقع فيه كل مطوّر أتمتة متصفح مرة واحدة بالضبط: تضيف --proxy-server=http://user:pass@host:port إلى علامات تشغيل Chrome، فيبدأ المتصفح على ما يرام، ثم تتجمّد كل صفحة على نافذة منبثقة للمصادقة لا يستطيع برنامجك النصي رؤيتها أو النقر عليها. يجرّد Chrome بصمت بيانات الاعتماد من علامة البروكسي. لا خطأ، ولا سطر سجل، فقط مربع حوار في متصفح لا أحد يراقبه.
هذا الدليل هو الخريطة الكاملة لطرق مصادقة البروكسي التي تعمل فعلًا في Selenium وPlaywright في 2026 — أيها تستخدم، وأيها تتجنّب، والكود الدقيق لكل منها. (لاختيار البروكسي واستراتيجية التناوب في هذه الأدوات، راجع استخدام البروكسيات مع Playwright وPuppeteer — هذا المقال يدور بحتًا حول تمرير بيانات الاعتماد.)
تستخرج عملاء HTTP عبر سطر الأوامر بيانات الاعتماد من عناوين URL للبروكسي وتُجيب عن استجابة 407 Proxy Authentication Required للبروكسي بترويسة Proxy-Authorization تلقائيًا. لا يفعل Chromium ذلك: يقبل --proxy-server فقط scheme://host:port، وعندما تعود استجابة 407 يعرض مربع حوار تفاعليًا. في الوضع بلا واجهة لا يوجد حتى مربع حوار — يفشل الطلب فحسب.
لذا فالسؤال ليس أبدًا "كيف أضع كلمة المرور في عنوان URL" — بل "أي طبقة تُجيب عن 407 نيابة عني." أربع إجابات تعمل، الأفضل أولًا.
حلّ Playwright المشكلة بشكل صحيح: يُجيب بنفسه عن تحديات مصادقة البروكسي عبر CDP. تذهب بيانات الاعتماد في خيارات التشغيل أو السياق:
# 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',
}
});
البروكسيات لكل سياق تعني أن عملية متصفح واحدة يمكنها تشغيل N من السياقات على N من الجلسات اللاصقة المختلفة — وهي أساس كل إعداد كشط جدّي في Playwright. إذا كنت تستخدم Playwright، فقد انتهيت؛ انتقل إلى قسم التحقق. كل ما يلي موجود لأن 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")
محاذير يجب أن تعرفها قبل الإنتاج:
النهج الكلاسيكي: إضافة مُولّدة صغيرة تضبط البروكسي وتُجيب عن المصادقة عبر 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=new (Chrome 109+) أو شغّل بواجهة؛ ولا تزال البرامج النصية الخلفية في Manifest V2 تعمل لإضافات الأتمتة المُحمّلة جانبيًا لكن راقب الجدول الزمني لإيقاف MV2 في Chrome — يحتاج مكافئ MV3 إلى service worker وإلى المستمع onAuthRequired نفسه.
شغّل بروكسي محلي صغير يحمل بيانات الاعتماد؛ وجّه المتصفح إلى localhost دون أي مصادقة على الإطلاق. يعمل مع كل متصفح، وكل برنامج تشغيل، وكل لغة، بواجهة أو بدونها:
# 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 (حيث لا تنطبق حيلة الإضافة) وللبيئات الغريبة مثل اختبار تطبيقات Electron. التكلفة: جزء متحرك إضافي للإشراف عليه، والتوجيه لكل سياق يتطلّب منفذ مُحوّل واحدًا لكل جلسة.
| الطريقة | تعمل في | بلا واجهة | جلسات لكل سياق | الحكم الإنتاجي |
|---|---|---|---|---|
| Playwright الأصلية | Playwright | نعم | نعم | الخيار الافتراضي |
| selenium-wire | Selenium (Py) | نعم | لكل برنامج تشغيل | جيدة عند نطاق متوسط |
| إضافة المصادقة | Selenium (أي لغة) | --headless=new فقط | لكل برنامج تشغيل | متينة، راقب MV3 |
| المُحوّل المحلي | كل شيء | نعم | منفذ واحد لكل جلسة | الحل البديل الشامل |
التراجع الصامت إلى عنوان IP الحقيقي هو وضع الفشل الذي يتسبب في حظر الحسابات. تحقّق بتأكيد من عنوان 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 — المضيف/المنفذ خاطئ أو عدم تطابق البروتوكول. اختبر السطر نفسه باستخدام curl -x أولًا؛ إذا نجح curl، فالمشكلة في توصيل متصفحك.--headless=new.لا تقرأ المتصفحات عناوين URL للبروكسي بصيغة user:pass@ — يجب أن يُجيب شيء ما عن 407 نيابة عنها. في Playwright يكون ذلك الشيء مدمجًا؛ وفي Selenium يكون selenium-wire، أو إضافة مصادقة مُولّدة، أو مُحوّل محلي. اختر حسب حزمتك من جدول المقارنة، ثم أكّد عنوان IP الخارج في كل تشغيل حتى لا يتمكن فشل مصادقة صامت أبدًا من تسريب عنوانك الحقيقي في منتصف الزحف.
رصيد سكني مجاني بحجم 500 ميجابايت — بوابة واحدة، لاصقة أو متناوبة، HTTP وSOCKS5.
ابدأ النسخة التجريبية المجانيةيحصل المستخدمون الجدد على 500MB عند التسجيل، بالإضافة إلى مكافأة على أول عملية شحن. العرض لفترة محدودة.