اسکریپت Selenium شما کار میکند، اما حالا باید صفحهها را همانطور ببینید که یک بازدیدکننده در آلمان میبیند، یا کار باید از سروری اجرا شود که سایت مقصد از قبل برایش محدودیت نرخ گذاشته است. پروکسی را اضافه میکنید و بهجای نتیجه، صفحهای خالی میگیرید، بی هیچ پیغام خطایی. علت معمولاً رمز است: استاندارد WebDriver هیچ فیلدی برای نام کاربری و رمز پروکسی ندارد، پس user:pass@host:port یا رد میشود یا بیصدا نادیده گرفته میشود.
این راهنما تنظیم پروکسی در Selenium (سلنیوم) را برای Chrome، Edge و Firefox شرح میدهد: روشهای احراز هویتی که امروز کار میکنند، SOCKS5، سایتهای HTTPS، چرخش IP و پیامهای خطا. همه نمونههای Python با Selenium 4.49، Chrome 154، Edge 153 و Firefox 156 روی Windows 11 اجرا شدهاند، در برابر یک پروکسی آزمایشی محلی که نام کاربری و رمز میخواهد.
Selenium چیست؟
Selenium مرورگرها را از طریق کد و بهصورت خودکار کنترل میکند. بیشتر برای آزمودن برنامههای وب به کار میرود، اما برای جمعآوری داده از صفحههایی که فقط با JavaScript کامل نمایش داده میشوند هم مناسب است. درست مثل یک کاربر، پنجره باز میکند، صفحه بار میکند، کلیک میکند، متن مینویسد، فرم میفرستد و محتوای صفحه را میخواند. کد شما کتابخانه Selenium را فرا میخواند، کتابخانه با یک درایور (ChromeDriver، msedgedriver یا geckodriver) حرف میزند و درایور از راه پروتکل W3C WebDriver مرورگر را میگرداند.
از مرورگرهای رایج پشتیبانی میکند، یعنی Chrome، Edge، Firefox و Safari، و کتابخانههای رسمی آن برای Python، Java، C#، Ruby و JavaScript در دسترساند. از نسخه 4.6 به بعد، Selenium Manager همراه Selenium عرضه میشود؛ این ابزار مرورگر نصبشده را پیدا میکند و درایور مناسب آن را دانلود میکند. هنوز میان ابزارها مردد هستید؟ تفاوت Playwright و Selenium: کدام را انتخاب کنیم؟ را ببینید.
پروکسی در Selenium چگونه کار میکند؟
در Selenium پروکسی به نشست مرورگر تعلق دارد، نه به یک درخواست تکی:
- پروکسی را در گزینههای مرورگر میگذارید: به شکل آرگومان Chrome یعنی
--proxy-server، یا به شکل شیءProxy(قابلیتproxyدر استاندارد WebDriver). - درایور مرورگر را با همین تنظیم راه میاندازد و این تنظیم تا
driver.quit()روی همه زبانهها اعمال میشود. - برای صفحه
https://مرورگر درخواستCONNECT host:443را به پروکسی میفرستد و یک تونل رمزگذاریشده باز میکند. برای صفحهhttp://نشانی کامل را به پروکسی میدهد. - اگر پروکسی ورود بخواهد، پاسخ 407 Proxy Authentication Required برمیگرداند. این همان مرحلهای است که استاندارد WebDriver پوشش نمیدهد.
- سایت مقصد IP خروجی پروکسی را میبیند. برای پروکسی دیگر، باید مرورگر تازهای راه بیندازید.
Chrome ترافیک پسزمینه خودش (بهروزرسانیها و سرویسهای حساب) را هم از پروکسی عبور میدهد و در پلنی که بر اساس گیگابایت حساب میشود، این ترافیک هم در مصرف شمرده میشود.
چگونه در Python از Selenium با پروکسی استفاده کنیم؟
گام 1: نصب Selenium. Selenium 4.49 به Python 3.10 یا جدیدتر نیاز دارد:
pip install seleniumگام 2: تهیه پروکسی. سرویس مناسب خود را از صفحه پروکسی انتخاب کنید. بخش «Endpoint Generator» در پنل کاربری Proxynet نشانی گیتوی، پورت و نام کاربریای را به شما میدهد که کشور، شهر و نشست انتخابی شما را در خود دارد. HTTP و SOCKS5 روی همان گیتوی اما با پورتهای جداگانه کار میکنند.
گام 3: آماده کردن درایور. از نسخه 4.6 به بعد، Selenium Manager در نخستین اجرا خودش درایور مناسب را دانلود میکند؛ نصب دستی ChromeDriver فقط در نسخههای قدیمیتر لازم بود. پارامتر executable_path که در آموزشهای قدیمی میبینید هم دیگر وجود ندارد. اگر رایانه برای دسترسی به اینترنت خودش به پروکسی نیاز دارد، متغیر SE_PROXY را برای دانلودهای Selenium Manager تنظیم کنید.
گام 4: راهاندازی مرورگر با پروکسی. برای پروکسیای که رمز نمیخواهد (لیست سفید IP، که پایینتر توضیح داده شده):
from selenium import webdriver
from selenium.webdriver.common.by import By
PROXY = "http://pr.proxynet.io:8000"
options = webdriver.ChromeOptions()
options.add_argument(f"--proxy-server={PROXY}")
options.add_argument("--headless") # remove to watch the browser
driver = webdriver.Chrome(options=options)
try:
driver.get("https://api.ipify.org/?format=json")
print(driver.find_element(By.TAG_NAME, "body").text) # {"ip": "<exit IP>"}
finally:
driver.quit()بهجای pr.proxynet.io:8000 نام میزبان و پورتی را که در پنل Proxynet دارید بگذارید. IP چاپشده باید IP خروجی پروکسی باشد. شیء Proxy در Selenium هم همین کار را انجام میدهد (options.proxy = Proxy({"proxyType": ProxyType.MANUAL, "httpProxy": "host:port", "sslProxy": "host:port"})) و در آزمایش ما هر دو روش ترافیک را به یک صورت از پروکسی عبور دادند.
چگونه در Selenium از پروکسی با نام کاربری و رمز استفاده کنیم؟
تعریف پروکسی در استاندارد W3C WebDriver برای نشانی پروکسی کلید دارد، اما برای نام کاربری یا رمز هیچ کلیدی ندارد. مستندات پروکسی Chromium هم میگوید Chrome از نام کاربری و رمزی که در تنظیمات پروکسی جاسازی شده باشد استفاده نمیکند. آرگومانی به نام --proxy-auth هم وجود ندارد، هرچند در برخی آموزشهای قدیمی آمده است. نتیجه آزمایشهای ما با پروکسیای که ورود میخواهد:
| آنچه امتحان کردیم | نتیجه |
|---|---|
--proxy-server=http://host:port بدون نام کاربری و رمز | پروکسی 407 برگرداند؛ هیچ استثنایی (exception) رخ نداد و صفحه خالی ماند |
--proxy-server=http://user:pass@host:port | صفحه خطای ERR_NO_SUPPORTED_PROXIES، بدون استثنا |
user:pass@host:port در شیء Proxy | صفحه بار شد، اما Chrome مستقیم و با IP خود ما وصل شد |
driver.network.add_auth_handler() در Selenium BiDi، با Chrome | پاسخ به چالش با خطای Invalid InterceptionId شکست خورد و سپس زمان انتظار به پایان رسید |
Fetch.continueWithAuth در CDP (تابع کمکی پایین) | در Chrome 154 و Edge 153 کار کرد |
| پورت بدون ورود (لیست سفید IP) | کار کرد |
ردیف سوم همان ردیف خطرناک است: اسکریپت ظاهراً کار میکند، در حالی که ترافیک اصلاً از پروکسی عبور نمیکند.
راه 1: لیست سفید IP
IP عمومی رایانهای را که اسکریپت روی آن اجرا میشود در فهرست مجاز پروکسی ثبت کنید تا پروکسی دیگر رمز نخواهد. آنگاه کد گام 4 بدون تغییر کار میکند و نسخههای Edge و Firefox هم همینطور. Proxynet تا 10 آدرس IP را میپذیرد. این روش برای سروری با IP ثابت مناسب است، نه لپتاپی که IP آن مدام عوض میشود؛ احراز هویت پروکسی: نام کاربری و رمز یا لیست سفید IP را ببینید.
راه 2: پاسخ به 407 از طریق Chrome DevTools Protocol
Chrome و Edge دامنه Fetch در DevTools Protocol را در اختیار میگذارند. وقتی handleAuthRequests روشن باشد، مرورگر درخواستی را که به نام کاربری و رمز نیاز دارد نگه میدارد و رویداد Fetch.authRequired را میفرستد که مقدار source آن Server یا Proxy است. تابع کمکی زیر فقط به چالشهای پروکسی پاسخ میدهد؛ بسته websocket-client همراه Selenium نصب میشود.
# proxy_auth.py
import json
import threading
import urllib.request
import websocket # installed together with selenium (websocket-client)
def attach_proxy_auth(driver, username, password):
"""Answers the tab's proxy 407 challenges over the Chrome DevTools Protocol."""
caps = driver.capabilities
vendor = caps.get("goog:chromeOptions") or caps.get("ms:edgeOptions") # Chrome or Edge
address = vendor["debuggerAddress"]
with urllib.request.urlopen(f"http://{address}/json") as resp:
targets = json.load(resp)
page = next(t for t in targets if t["type"] == "page")
ws = websocket.create_connection(page["webSocketDebuggerUrl"], suppress_origin=True)
counter = {"id": 0}
def send(method, params=None):
counter["id"] += 1
ws.send(json.dumps({"id": counter["id"], "method": method, "params": params or {}}))
def listen():
while True:
try:
msg = json.loads(ws.recv())
except Exception:
return # the browser was closed
method = msg.get("method")
params = msg.get("params", {})
if method == "Fetch.requestPaused":
send("Fetch.continueRequest", {"requestId": params["requestId"]})
elif method == "Fetch.authRequired":
if params["authChallenge"]["source"] == "Proxy":
answer = {"response": "ProvideCredentials",
"username": username, "password": password}
else:
answer = {"response": "Default"} # the site's own login is not ours to answer
send("Fetch.continueWithAuth", {"requestId": params["requestId"],
"authChallengeResponse": answer})
send("Fetch.enable", {"handleAuthRequests": True})
while json.loads(ws.recv()).get("id") != counter["id"]:
pass # wait until interception is active before the first driver.get()
threading.Thread(target=listen, daemon=True).start()
return wsبرای استفاده از آن، پس از راهاندازی درایور فقط یک خط لازم است:
from selenium import webdriver
from proxy_auth import attach_proxy_auth
options = webdriver.ChromeOptions()
options.add_argument("--proxy-server=http://pr.proxynet.io:8000")
driver = webdriver.Chrome(options=options)
attach_proxy_auth(driver, "user", "pass")
driver.get("https://api.ipify.org/?format=json")محدودیتها: تابع کمکی فقط زبانهای را پوشش میدهد که به آن وصل شده است، پس پنجره تازه بدون آن شروع میشود. با رمز اشتباه، Chrome خطای ERR_TOO_MANY_RETRIES را نشان میدهد.
Selenium Wire و افزونههای پروکسی چه وضعی دارند؟
مخزن Selenium Wire در 3 ژانویه 2024 بایگانی شد و در یک محیط تازه Python 3.13 دستور from seleniumwire import webdriver برای ما با خطای ModuleNotFoundError: No module named 'pkg_resources' شکست خورد. افزونههای احراز هویت به سوئیچ --load-extension وابسته بودند که نسخههای رسمی Chrome از نسخه 137 به بعد آن را نادیده میگیرند؛ فقط Chrome for Testing و Chromium هنوز آن را میپذیرند. SeleniumBase مقدار proxy="user:pass@host:port" را میپذیرد و ورود را خودش انجام میدهد؛ پروکسی با SeleniumBase: احراز هویت و چرخش را ببینید.
در Selenium از کدام روش پروکسی استفاده کنیم؟
| روش | Chrome / Edge | Firefox | رمز | وضعیت در 2026 |
|---|---|---|---|---|
آرگومان --proxy-server | بله | خیر، از ترجیحات شبکه استفاده کنید | خیر | پشتیبانیشده |
شیء Proxy | بله | بله | نادیده گرفته میشود | پشتیبانیشده |
| لیست سفید IP | بله | بله | لازم نیست | پشتیبانیشده |
| تابع کمکی CDP | بله | خیر | بله | آزمودهشده، کار میکند |
add_auth_handler در BiDi | در Chrome شکست خورد | خطای پنجره ورود | در تئوری | هنوز قابل اتکا نیست |
| Selenium Wire | import شکست میخورد | import شکست میخورد | بله | بایگانیشده |
| افزونه احراز هویت | فقط Chrome for Testing | قالب جداگانه | بله | از نسخه 137 در Chrome از کار افتاده |
در Selenium چگونه برای Microsoft Edge پروکسی تنظیم کنیم؟
Edge بر پایه Chromium ساخته شده است، پس EdgeOptions همان آرگومان را میپذیرد و Selenium Manager درایور msedgedriver را دانلود میکند:
from selenium import webdriver
options = webdriver.EdgeOptions()
options.add_argument("--proxy-server=http://pr.proxynet.io:8000")
driver = webdriver.Edge(options=options)تابع کمکی CDP با Edge هم کار میکند؛ با Edge 153 و پروکسی آزمایشی رمزدار، صفحه از مسیر پروکسی بار شد.
چگونه در Selenium با Firefox پروکسی تنظیم کنیم؟
Firefox آرگومان --proxy-server را نمیخواند. ترجیحات شبکه (preferences) آن را تنظیم کنید، یا شیء Proxy را بدهید که geckodriver آن را به همین ترجیحات تبدیل میکند. Firefox روی رایانه آزمایشی ما نصب نبود؛ Selenium Manager در نخستین اجرا Firefox 156 را دانلود کرد.
from selenium import webdriver
options = webdriver.FirefoxOptions()
options.set_preference("network.proxy.type", 1) # 1 = manual configuration
options.set_preference("network.proxy.http", "pr.proxynet.io")
options.set_preference("network.proxy.http_port", 8000)
options.set_preference("network.proxy.ssl", "pr.proxynet.io") # used for https:// pages
options.set_preference("network.proxy.ssl_port", 8000)
driver = webdriver.Firefox(options=options)برای SOCKS5، ترجیحهای network.proxy.socks و network.proxy.socks_port را تنظیم کنید و network.proxy.socks_version را روی 5 بگذارید. در این حالت Firefox نام دامنه را به پروکسی میفرستد، چون network.proxy.socks5_remote_dns بهطور پیشفرض روشن است. ترجیح قدیمیتر network.proxy.socks_remote_dns که هنوز در بسیاری از آموزشها دیده میشود، در Firefox 156 برای SOCKS5 هیچ اثری نداشت، اما وقتی socks5_remote_dns را روی False گذاشتیم، Firefox نامها را روی رایانه خودمان به IP تبدیل کرد. Firefox هیچ ترجیحی برای نام کاربری و رمز پروکسی ندارد و تابع کمکی CDP هم روی آن کار نمیکند. add_auth_handler در Selenium BiDi نام کاربری و رمز ما را فرستاد، اما بارگذاری صفحه به خاطر پنجره ورود پروکسی باز هم با UnexpectedAlertPresentException شکست خورد؛ پس در Firefox از لیست سفید IP استفاده کنید.
آیا Selenium میتواند از پروکسی SOCKS5 استفاده کند؟
بله، بدون رمز: --proxy-server=socks5://host:port. در آزمایش ما Chrome نام دامنه را بهجای تبدیل محلی، به پروکسی فرستاد؛ مستندات Chromium هم تأیید میکند که با SOCKS5، تبدیل نام همیشه در سمت پروکسی انجام میشود.
با رمز، خیر: Chromium از احراز هویت SOCKS5 پشتیبانی نمیکند و driver.get() خطای net::ERR_SOCKS_CONNECTION_FAILED داد. تابع کمکی CDP هم کمکی نمیکند، چون SOCKS اصلاً پاسخ 407 ندارد که بتوان به آن جواب داد. از پورت SOCKS5 با لیست سفید یا از پورت HTTP با تابع کمکی استفاده کنید. توضیح بیشتر در پروکسی SOCKS5 چیست؟ نحوه کار و تفاوت SOCKS4 و SOCKS5 و تفاوت پروکسی SOCKS و HTTP: کدام را انتخاب کنیم؟ آمده است؛ پروکسی SOCKS5 در Proxynet روی پورت جداگانه همان گیتوی کار میکند.
آیا Selenium از طریق پروکسی با سایتهای HTTPS کار میکند؟
بله. نشانی پروکسی حتی وقتی همه صفحهها https:// هستند طرح http:// را نگه میدارد: مرورگر یک تونل CONNECT باز میکند و TLS از یک سر تا سر دیگر میان مرورگر و سایت برقرار است، پس پروکسی نام میزبان را میبیند اما محتوا را نه. به همین دلیل شیء Proxy علاوه بر httpProxy به sslProxy هم نیاز دارد؛ وقتی فقط httpProxy را گذاشتیم، صفحههای https:// ما مستقیم و بدون پروکسی رفتند.
طرح https:// در --proxy-server خود اتصال به پروکسی را رمزگذاری میکند؛ پروکسی HTTPS را ببینید.
چگونه در Java پروکسی را با Selenium یکپارچه کنیم؟
Java از همان شیء Proxy استفاده میکند. اینجا هم همان قاعده برقرار است: نام کاربری و رمز در آدرس پروکسی نوشته نمیشود. نمونههای رایجی که user:pass@ را در setHttpProxy میگذارند، در آزمایش ما باعث شدند Chrome اصلاً از پروکسی عبور نکند؛ برای همین نسخه زیر به لیست سفید IP تکیه میکند. این نسخه System.setProperty("webdriver.chrome.driver", …) را هم ندارد، چون Selenium Manager درایور را پیدا میکند. Selenium 4 به Java 11 یا جدیدتر نیاز دارد.
import org.openqa.selenium.Proxy;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
public class SeleniumProxyExample {
public static void main(String[] args) {
// No credentials here: the machine's IP is on the proxy's whitelist
String proxyAddress = "pr.proxynet.io:8000";
Proxy proxy = new Proxy();
proxy.setHttpProxy(proxyAddress);
proxy.setSslProxy(proxyAddress);
ChromeOptions options = new ChromeOptions();
options.setProxy(proxy);
// Selenium Manager finds or downloads the matching ChromeDriver
WebDriver driver = new ChromeDriver(options);
try {
driver.get("https://api.ipify.org/?format=json");
System.out.println(driver.getPageSource());
} finally {
driver.quit();
}
}
}options.addArguments("--proxy-server=http://pr.proxynet.io:8000") معادل آرگومان Python است. این نمونه را بر اساس مستندات Selenium نوشتهایم و اجرا نکردهایم، چون روی رایانه آزمایشی فقط Java 8 نصب است.
چگونه در Selenium پروکسیهای مسکونی را بچرخانیم؟
پروکسی در طول عمر یک مرورگر ثابت است، پس چرخش یعنی راهاندازی مرورگر تازه:
- گیتوی چرخشی. با پروکسی چرخشی IP خروجی در سمت گیتوی عوض میشود و کد شما یک نشانی را نگه میدارد. اتصالهای بارگذاری یک صفحه ممکن است از IPهای متفاوت خارج شوند: برای فهرست محصولات مشکلی نیست، اما برای فرایند ورود به حساب مشکلساز است.
- نشست ثابت. با پروکسی با نشست ثابت IP به مدت 1 تا 60 دقیقه ثابت میماند. به هر مرورگر نام کاربری نشست خودش را از «Endpoint Generator» بدهید: یک مرورگر، یک نشست، یک IP خروجی.
هر دو حالت با IPهای پروکسی مسکونی کار میکنند؛ چرخش IP چیست و چگونه کار میکند؟ و چرخاندن پروکسی در Python: راهنما همراه با کد را ببینید. نوع پروکسی هم به مقصد بستگی دارد: IP مسکونی برای مقصدهایی با بررسی سختگیرانه، پروکسی دیتاسنتر برای برداشتهای سریع از سایتهای کمحساسیت، و پروکسی ISP وقتی کاری چندمرحلهای باید بیش از 60 دقیقه روی همان آدرس بماند.
نمونه کامل: مرورگرهای موازی با تلاش دوباره
این اسکریپت شش صفحه از quotes.toscrape.com را میخواند، سایتی تمرینی که صفحههایش با JavaScript ساخته میشوند. سه نمونه Chrome را همزمان اجرا میکند، در هر تلاش مرورگر تازهای راه میاندازد، برای صرفهجویی در ترافیک تصویرها را مسدود میکند و خطاهای موقت را با تأخیر فزاینده دوباره امتحان میکند. خطاهایی که تلاش دوباره درستشان نمیکند، از جمله خطاهایی که فقط صفحه خطای Chrome را نشان میدهند، کار را فوراً متوقف میکنند.
import random
import re
import time
from concurrent.futures import ThreadPoolExecutor, as_completed
from selenium import webdriver
from selenium.common.exceptions import TimeoutException, WebDriverException
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from proxy_auth import attach_proxy_auth
PROXY_SERVER = "http://pr.proxynet.io:8000"
PROXY_USER = "user"
PROXY_PASS = "pass"
URLS = [f"https://quotes.toscrape.com/js/page/{n}/" for n in range(1, 7)]
WORKERS = 3 # browsers open at the same time
ATTEMPTS = 3
# A retry will not fix these: check the address, port and credentials first
FATAL = ("ERR_PROXY_CONNECTION_FAILED", "ERR_NO_SUPPORTED_PROXIES",
"ERR_SOCKS_CONNECTION_FAILED", "ERR_TOO_MANY_RETRIES")
def new_driver():
options = webdriver.ChromeOptions()
options.add_argument(f"--proxy-server={PROXY_SERVER}")
options.add_argument("--headless")
# Skip images: less traffic through the proxy
options.add_experimental_option("prefs", {"profile.managed_default_content_settings.images": 2})
driver = webdriver.Chrome(options=options)
driver.set_page_load_timeout(30)
attach_proxy_auth(driver, PROXY_USER, PROXY_PASS)
return driver
def scrape(url):
for attempt in range(ATTEMPTS):
driver = new_driver() # a fresh browser, and a fresh proxy connection, on every attempt
try:
driver.get(url)
# Some proxy errors open Chrome's error page without raising an exception
if driver.execute_script("return document.body.className") == "neterror":
code = re.search(r"ERR_[A-Z_]+", driver.page_source)
raise WebDriverException(code.group(0) if code else "Chrome error page")
WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.CSS_SELECTOR, "div.quote span.text"))
)
quotes = driver.find_elements(By.CSS_SELECTOR, "div.quote span.text")
return url, [q.text for q in quotes]
except (TimeoutException, WebDriverException) as exc:
if any(code in str(exc) for code in FATAL) or attempt == ATTEMPTS - 1:
raise
time.sleep(2**attempt + random.random()) # exponential backoff with jitter
finally:
driver.quit()
with ThreadPoolExecutor(max_workers=WORKERS) as pool:
futures = [pool.submit(scrape, url) for url in URLS]
for future in as_completed(futures):
try:
url, quotes = future.result()
print(f"{url}: {len(quotes)} quotes")
except Exception as exc:
print("failed:", str(exc).splitlines()[0])هر شش صفحه در حدود 22 ثانیه، هر کدام 10 نقلقول برگرداندند؛ یک پورت بسته همه کارها را با net::ERR_PROXY_CONNECTION_FAILED متوقف کرد و یک رمز اشتباه با ERR_TOO_MANY_RETRIES. مقدار WORKERS را معقول نگه دارید: هر کدام یک Chrome کامل است و نشستهای موازی بیش از حد به خطای 429 Too Many Requests میانجامند.
چگونه مطمئن شویم Selenium واقعاً از پروکسی استفاده میکند؟
در مرورگری که از پروکسی عبور میکند، یک صفحه نمایش IP مانند api.ipify.org را باز کنید و نتیجه را با IP خودتان مقایسه کنید؛ اگر یکی باشند، ترافیک از پروکسی عبور نمیکند. ترافیک باید در پنل کاربری شما هم دیده شود. WebRTC همچنان میتواند IP محلی را فاش کند؛ نشت WebRTC و DNS: چیست و چگونه جلوی آن را بگیریم را ببینید. روال کامل آزمون در آیا پروکسی کار میکند؟ چگونه پروکسی را آزمایش کنیم و یک بررسی یکخطی در ترمینال در استفاده از cURL با پروکسی آمده است.
خطاهای رایج پروکسی در Selenium و راه رفع آنها
پیامها همانطور که در آزمایشهای ما ظاهر شدند. کدهای Chrome یا در متن استثنا میآیند (unknown error: net::ERR_…) یا فقط در صفحه خطا.
| پیام | علت | راهحل |
|---|---|---|
صفحه خالی، driver.title خالی، بدون استثنا | پروکسی 407 برگرداند و نام کاربری و رمزی فرستاده نشد | IP را در لیست سفید بگذارید یا از تابع کمکی CDP استفاده کنید |
ERR_NO_SUPPORTED_PROXIES (صفحه خطا) | نام کاربری و رمز داخل --proxy-server | user:pass@ را از آرگومان حذف کنید |
net::ERR_PROXY_CONNECTION_FAILED | روی آن میزبان و پورت چیزی گوش نمیدهد | نشانی، پورت و فایروال را بررسی کنید |
net::ERR_TUNNEL_CONNECTION_FAILED | پروکسی نتوانست تونل را باز کند | اول میزبان مقصد و بعد پروکسی را بررسی کنید |
net::ERR_SOCKS_CONNECTION_FAILED | پروکسی SOCKS5 رمز میخواهد | پورت HTTP با تابع کمکی، یا لیست سفید |
ERR_TOO_MANY_RETRIES (صفحه خطا) | پروکسی نام کاربری و رمز تابع کمکی را نپذیرفت | نام کاربری و رمز را دوباره کپی کنید |
TypeError: WebDriver.__init__() got an unexpected keyword argument 'executable_path' | کد نوشتهشده برای Selenium 3 | آن را حذف کنید؛ Selenium Manager درایور را پیدا میکند |
… unexpected keyword argument 'chrome_options' | همان مشکل، با نام قدیمیتر | از options= استفاده کنید |
Timed out receiving message from renderer | بارگذاری صفحه هیچوقت تمام نشد | پروکسی را بررسی کنید، سپس دوباره امتحان کنید |
خطاهای اتصال در کلاینتهای HTTP ساده Python را سطر به سطر در خطای Max Retries Exceeded With URL چیست و چگونه رفع میشود؟ خواندهایم.
کاربردها
- رصد قیمت در فروشگاههایی که به JavaScript وابستهاند، از همان بازاری که در آن میفروشید: رصد قیمت رقبا در فروشگاه اینترنتی و رصد قیمت.
- بومیسازی و QA: بارگذاری سایت خودتان از چند کشور پیش از انتشار؛ تست اپلیکیشن را ببینید.
- راستیآزمایی تبلیغات: بررسی آگهیهای خودتان در منطقههایی که برایشان هزینه میکنید؛ راستیآزمایی تبلیغات را ببینید.
- جمعآوری داده از صفحههایی که به JavaScript نیاز دارند: استخراج داده.
پروکسی جایی را که درخواست از آن میآید عوض میکند، نه آنچه سایت اجازه میدهد: robots.txt و شرایط استفاده سایت را بخوانید، نرخ درخواست را پایین نگه دارید و اگر API رسمی وجود دارد آن را ترجیح دهید. پروکسی خودکارسازی را هم پنهان نمیکند؛ مرورگری که زیر کنترل WebDriver است، همانطور که استاندارد میخواهد، مقدار navigator.webdriver را true گزارش میکند.
راهنمای انتخاب
| نیاز | پیشنهاد |
|---|---|
| سرور با IP ثابت | لیست سفید IP + --proxy-server، بدون رمز در کد |
| لپتاپ یا CI runner با IP متغیر | پورت HTTP + تابع کمکی CDP |
| Firefox | ترجیحات شبکه + لیست سفید IP |
| SOCKS5 | socks5:// در --proxy-server، فقط با لیست سفید |
| فرایند ورود به حساب یا پرداخت | نشست ثابت، یک مرورگر برای هر نشست |
| صفحههای مستقل زیاد | گیتوی چرخشی |
| پروکسی متفاوت برای هر صفحه در یک مرورگر | پروکسی جداگانه برای هر context در Playwright؛ Playwright چیست و چگونه با پروکسی استفاده میشود؟ |
پرسشهای متداول
آیا Selenium میتواند از پروکسی با نام کاربری و رمز استفاده کند؟
نه از راه گزینههای استاندارد، چون این گزینهها فیلدی برای نام کاربری و رمز ندارند. در Chrome و Edge تابع کمکی DevTools همین نوشته به 407 پروکسی پاسخ میدهد؛ در هر مرورگری هم لیست سفید IP نیاز به رمز را از میان برمیدارد.
آیا Selenium Wire در 2026 هنوز کار میکند؟
این کتابخانه در 3 ژانویه 2024 بایگانی شد و در یک محیط تازه Python 3.13 برای ما import نشد، چون به pkg_resources وابسته است که نسخههای فعلی setuptools دیگر آن را همراه ندارند. از تابع کمکی یا لیست سفید استفاده کنید.
چگونه بدون بستن مرورگر پروکسی را عوض کنیم؟
پروکسی هنگام شروع نشست ثابت میشود: driver.quit() را فراخوانی کنید و درایور تازهای راه بیندازید. برای IP تازه در هر صفحه درون یک مرورگر، از گیتوی چرخشی استفاده کنید، یا از Playwright که برای هر context پروکسی جداگانه میپذیرد.
آیا پروکسی در حالت headless کار میکند؟
بله. --proxy-server و تابع کمکی CDP با --headless و بدون آن یکسان رفتار میکنند؛ همه نمونههای این نوشته در حالت headless اجرا شدند.
آیا در Selenium میتوان از پروکسی SOCKS5 با احراز هویت استفاده کرد؟
در Chrome و Edge نه، چون از احراز هویت SOCKS5 پشتیبانی نمیکنند؛ Firefox 156 هم به پروکسی ما فقط روش بدون رمز را پیشنهاد داد. SOCKS5 را با لیست سفید به کار ببرید، یا پورت HTTP را با رمز.
چرا سایت هنوز IP واقعی من را نشان میدهد؟
معمولاً پروکسی اصلاً اعمال نشده است: نام کاربری و رمز داخل شیء Proxy باعث میشود Chrome مستقیم وصل شود، و شیء Proxy بدون sslProxy صفحههای https:// را بدون پروکسی رها میکند. اگر IP درست است اما موقعیت نادرست به نظر میرسد، نشت WebRTC را آزمایش کنید.
خلاصه
Selenium پروکسی را یک بار برای هر نشست مرورگر تنظیم میکند: --proxy-server برای Chrome و Edge، و ترجیحات شبکه یا شیء Proxy برای Firefox. برای احراز هویت از لیست سفید IP استفاده کنید یا در Chrome و Edge از تابع کمکی DevTools که به 407 پاسخ میدهد؛ Selenium Wire و افزونههایی که از خط فرمان بارگذاری میشوند به بنبست رسیدهاند. SOCKS5 فقط بدون رمز کار میکند و چرخش یعنی یک مرورگر برای هر IP یا نشست. وقتی راهاندازی آماده شد، پلن خود را از صفحه پروکسی Proxynet انتخاب کنید و مشخصات گیتوی را از «Endpoint Generator» بردارید.




