# Ludax proxies in Selenium: guide for AI assistants

> Give this file to your AI assistant (ChatGPT, Claude, Cursor, Copilot) and it can write working Selenium code for Ludax Proxy in Python, Java, JavaScript, C# or Ruby. Human-readable version: https://ludaxproxy.com/docs/selenium

You are helping a developer use Ludax residential proxies, which need a username and a password, in Selenium with Chrome. Follow the rules below exactly; each method was tested on 2026-10-23 with Selenium 4.51 and Chrome 155.

## Rules

- Set the proxy with Chrome's `--proxy-server=http://<gateway>` (for example `--proxy-server=http://gw.ludaxproxy.com:7777`). The flag takes **no** username or password: Chrome then asks for the login, and Selenium must answer it through Chrome's DevTools (Fetch.authRequired). Register the answer **before** the first `get()`.
- The working method per language:
  - **Java:** `((HasAuthentication) driver).register(UsernameAndPassword.of(user, pass))`.
  - **JavaScript (selenium-webdriver):** `await driver.register(user, pass, await driver.createCDPConnection("page"))`.
  - **C#:** `driver.Manage().Network.AddAuthenticationHandler(new NetworkAuthenticationHandler { UriMatcher = _ => true, Credentials = new PasswordCredentials(user, pass) })`, then `await network.StartMonitoring()`.
  - **Ruby:** `driver.register(username:, password:)`; needs the `selenium-devtools` gem.
  - **Python:** the DevTools connection (`driver.bidi_connection()` with trio): enable `fetch` with `handle_auth_requests=True`, answer `AuthRequired` with `continue_with_auth` and continue every `RequestPaused`. Use the `ludax_login.py` helper below.
- **Do not suggest** these; they did not answer a proxy login in tests: the WebDriver BiDi handler (`driver.network.add_auth_handler` / `add_authentication_handler` in Python), a Chrome extension (Chrome 137+ ignores `--load-extension`, and a `.crx` did not work either), Selenium Wire (unmaintained), or Firefox (its proxy login dialog stays open). For Firefox, suggest Playwright.
- Selenium's DevTools support covers the newest Chrome versions: keep Selenium (and `selenium-devtools` in Ruby) up to date.
- **One session token per browser** (`-session-<TOKEN>-time-<MINUTES>`): a page is many connections, and without a token each can leave from a new IP. A new browser with a new token is how to rotate.
- Use the standard gateways (Residential `gw.ludaxproxy.com:7777`, Premium `gw.ludaxproxy.com:8080`), never the TLS gateways: Chrome already sends a real browser handshake.
- Match the browser to the exit: `--lang=de-DE` and the DevTools command `Emulation.setTimezoneOverride` with `{"timezoneId": "Europe/Berlin"}`.
- Save bandwidth (plans are priced per GB): Chrome preference `profile.managed_default_content_settings.images` = 2.
- Errors: `net::ERR_TUNNEL_CONNECTION_FAILED` is a gateway 502 (retry with backoff); a blank page with no error means the login was never answered; "This site can't be reached" after a login means it was refused (fix the credentials; 30 failed logins in 5 minutes block the client IP for 10 minutes); `net::ERR_PROXY_CONNECTION_FAILED` means the gateway was not reached.

## Credentials

- **Username:** the product prefix (`resi-` or `premi-`), then the developer's account name from the dashboard (Generate), for example `resi-lx_k3m9q2p7xa`. The account name is `lx_` and 10 characters, the same for every plan. Never invent one: ask the developer, or use a placeholder such as `YOUR_USERNAME`.
- **Password:** the plan's own password (16 hexadecimal characters, one per plan), then the options, in this order: `-session-<TOKEN>-time-<MINUTES>`, then `-country-<cc>`, `-state-<code>`, `-city-<name>` (and `-asn-<number>`, `-os-<device>` on Premium). Use a placeholder such as `YOUR_PASSWORD`, or read it from an environment variable. Never put options in the username.
- **Sessions:** without `-session-` every new connection leaves from a new IP. `-session-<TOKEN>-time-<MINUTES>` keeps one IP for every connection that sends the same token (TOKEN: 3 to 24 letters or digits; MINUTES: 1 to 1000; Premium holds a session at least 3 minutes). Always send `-time-`: without it a session lasts 1 minute. On the TLS gateways add `-sameip` after the time, or only the browser profile is held.
- **Location:** `-country-` takes a lower-case ISO code (`us`, `de`, `jp`); `-state-` and `-city-` follow it (`-country-de-state-by-city-munich`); on Premium the state is its name without spaces (`-country-us-state-illinois-city-chicago`), in any of 219 countries. `-os-` (Premium) takes `windows`, `android`, `ios` or `macos`. With no free exit in that city or region the request falls back to the country. Codes for every country: https://ludaxproxy.com/locations
- **The port picks the product:** a plan's password works only on its own product's gateway, and the prefix must match it.

## Products and gateways in force

| Product | Username prefix | HTTP and HTTPS | SOCKS5 | Browser TLS | Sticky session |
| --- | --- | --- | --- | --- | --- |
| Residential | `resi-` | `gw.ludaxproxy.com:7777` | `gw.ludaxproxy.com:7575` | No | up to 1000 min |
| Residential TLS | `resi-` | `gw.ludaxproxy.com:9999` | none | Yes | up to 1000 min |
| Residential Premium | `premi-` | `gw.ludaxproxy.com:8080` | `gw.ludaxproxy.com:1080` | No | up to 1000 min |
| Residential Premium TLS | `premi-` | `gw.ludaxproxy.com:8081` | none | Yes | up to 1000 min |

## Check the connection

`GET https://api.ludaxproxy.com/whoami` through the proxy returns JSON: `ip`, `country` (full name), `type`, `tls_profile` (the browser the TLS handshake matches) and `latency_ms`. Add `?full=1` for a `debug` block with the JA4 fingerprint, the HTTP/2 fingerprint, the ASN and the User-Agent that arrived.

## Tested examples

The same code as on https://ludaxproxy.com/docs/selenium, in five languages. Replace `lx_k3m9q2p7xa` and `YOUR_PASSWORD` with the developer's credentials.

### Python helper: answer the proxy login through DevTools

```python
"""Answers the Ludax proxy's login in Chrome through Selenium's DevTools connection."""
import trio  # installed with selenium


def with_proxy_login(driver, username, password, work):
    """Runs work(driver) while Chrome's proxy login is answered with username and password."""

    async def main():
        async with driver.bidi_connection() as connection:
            session, devtools = connection.session, connection.devtools
            await session.execute(devtools.fetch.enable(handle_auth_requests=True))

            async def answer_login():
                async for event in session.listen(devtools.fetch.AuthRequired):
                    await session.execute(devtools.fetch.continue_with_auth(
                        event.request_id,
                        devtools.fetch.AuthChallengeResponse("ProvideCredentials", username, password)))

            async def resume_requests():
                async for event in session.listen(devtools.fetch.RequestPaused):
                    await session.execute(devtools.fetch.continue_request(event.request_id))

            async with trio.open_nursery() as nursery:
                nursery.start_soon(answer_login)
                nursery.start_soon(resume_requests)
                result = await trio.to_thread.run_sync(work, driver)
                nursery.cancel_scope.cancel()
        return result

    return trio.run(main)
```

### First request

**Python** (`first_request.py`)

```python
from selenium import webdriver
from ludax_login import with_proxy_login

options = webdriver.ChromeOptions()
options.add_argument("--proxy-server=http://gw.ludaxproxy.com:7777")
driver = webdriver.Chrome(options=options)


def work(driver):
    driver.get("https://api.ludaxproxy.com/whoami")
    print(driver.find_element("tag name", "body").text)


try:
    with_proxy_login(driver, "resi-lx_k3m9q2p7xa", "YOUR_PASSWORD-country-us", work)
finally:
    driver.quit()
```

**Java** (`FirstRequest.java`)

```java
import org.openqa.selenium.By;
import org.openqa.selenium.HasAuthentication;
import org.openqa.selenium.UsernameAndPassword;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;

public class FirstRequest {
  public static void main(String[] args) {
    ChromeOptions options = new ChromeOptions();
    options.addArguments("--proxy-server=http://gw.ludaxproxy.com:7777");
    WebDriver driver = new ChromeDriver(options);
    try {
      // Chrome asks for the proxy login; Selenium answers it through DevTools
      ((HasAuthentication) driver).register(
          UsernameAndPassword.of("resi-lx_k3m9q2p7xa", "YOUR_PASSWORD-country-us"));
      driver.get("https://api.ludaxproxy.com/whoami");
      System.out.println(driver.findElement(By.tagName("body")).getText());
    } finally {
      driver.quit();
    }
  }
}
```

**JavaScript** (`first_request.mjs`)

```javascript
import { Builder, By } from "selenium-webdriver";
import chrome from "selenium-webdriver/chrome.js";

const options = new chrome.Options().addArguments("--proxy-server=http://gw.ludaxproxy.com:7777");
const driver = await new Builder().forBrowser("chrome").setChromeOptions(options).build();
try {
  // Chrome asks for the proxy login; Selenium answers it through DevTools
  const cdp = await driver.createCDPConnection("page");
  await driver.register("resi-lx_k3m9q2p7xa", "YOUR_PASSWORD-country-us", cdp);
  await driver.get("https://api.ludaxproxy.com/whoami");
  console.log(await driver.findElement(By.css("body")).getText());
} finally {
  await driver.quit();
}
```

**C#** (`FirstRequest.cs`)

```csharp
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

var options = new ChromeOptions();
options.AddArgument("--proxy-server=http://gw.ludaxproxy.com:7777");
using var driver = new ChromeDriver(options);

// Chrome asks for the proxy login; Selenium answers it through DevTools
var network = driver.Manage().Network;
network.AddAuthenticationHandler(new NetworkAuthenticationHandler
{
    UriMatcher = _ => true,
    Credentials = new PasswordCredentials("resi-lx_k3m9q2p7xa", "YOUR_PASSWORD-country-us"),
});
await network.StartMonitoring();

driver.Navigate().GoToUrl("https://api.ludaxproxy.com/whoami");
Console.WriteLine(driver.FindElement(By.TagName("body")).Text);
driver.Quit();
```

**Ruby** (`first_request.rb`)

```ruby
require "selenium-webdriver"

options = Selenium::WebDriver::Options.chrome(args: ["--proxy-server=http://gw.ludaxproxy.com:7777"])
driver = Selenium::WebDriver.for(:chrome, options: options)
begin
  # Chrome asks for the proxy login; Selenium answers it through DevTools
  driver.register(username: "resi-lx_k3m9q2p7xa", password: "YOUR_PASSWORD-country-us")
  driver.get("https://api.ludaxproxy.com/whoami")
  puts driver.find_element(tag_name: "body").text
ensure
  driver.quit
end
```

### One IP per browser (rotation by browser)

**Python** (`sticky.py`)

```python
import json
import secrets
from selenium import webdriver
from ludax_login import with_proxy_login

for job in ["account-1", "account-2", "account-3"]:
    options = webdriver.ChromeOptions()
    options.add_argument("--proxy-server=http://gw.ludaxproxy.com:7777")
    driver = webdriver.Chrome(options=options)
    # a new session token = a new IP, held by this browser for 30 minutes
    password = f"YOUR_PASSWORD-session-{secrets.token_hex(4)}-time-30-country-us"

    def work(driver):
        driver.get("https://api.ludaxproxy.com/whoami")
        print(job, json.loads(driver.find_element("tag name", "body").text)["ip"])

    try:
        with_proxy_login(driver, "resi-lx_k3m9q2p7xa", password, work)
    finally:
        driver.quit()
```

**Java** (`Sticky.java`)

```java
import java.security.SecureRandom;
import java.util.HexFormat;
import org.openqa.selenium.By;
import org.openqa.selenium.HasAuthentication;
import org.openqa.selenium.UsernameAndPassword;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;

public class Sticky {
  public static void main(String[] args) {
    SecureRandom random = new SecureRandom();
    for (String job : new String[] {"account-1", "account-2", "account-3"}) {
      ChromeOptions options = new ChromeOptions();
      options.addArguments("--proxy-server=http://gw.ludaxproxy.com:7777");
      WebDriver driver = new ChromeDriver(options);
      try {
        // a new session token = a new IP, held by this browser for 30 minutes
        byte[] bytes = new byte[4];
        random.nextBytes(bytes);
        String password = "YOUR_PASSWORD-session-" + HexFormat.of().formatHex(bytes) + "-time-30-country-us";
        ((HasAuthentication) driver).register(UsernameAndPassword.of("resi-lx_k3m9q2p7xa", password));
        driver.get("https://api.ludaxproxy.com/whoami");
        System.out.println(job + " " + driver.findElement(By.tagName("body")).getText());
      } finally {
        driver.quit();
      }
    }
  }
}
```

**JavaScript** (`sticky.mjs`)

```javascript
import { randomBytes } from "node:crypto";
import { Builder, By } from "selenium-webdriver";
import chrome from "selenium-webdriver/chrome.js";

for (const job of ["account-1", "account-2", "account-3"]) {
  const options = new chrome.Options().addArguments("--proxy-server=http://gw.ludaxproxy.com:7777");
  const driver = await new Builder().forBrowser("chrome").setChromeOptions(options).build();
  try {
    // a new session token = a new IP, held by this browser for 30 minutes
    const password = `YOUR_PASSWORD-session-${randomBytes(4).toString("hex")}-time-30-country-us`;
    await driver.register("resi-lx_k3m9q2p7xa", password, await driver.createCDPConnection("page"));
    await driver.get("https://api.ludaxproxy.com/whoami");
    console.log(job, JSON.parse(await driver.findElement(By.css("body")).getText()).ip);
  } finally {
    await driver.quit();
  }
}
```

**C#** (`Sticky.cs`)

```csharp
using System.Security.Cryptography;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

foreach (var job in new[] { "account-1", "account-2", "account-3" })
{
    var options = new ChromeOptions();
    options.AddArgument("--proxy-server=http://gw.ludaxproxy.com:7777");
    using var driver = new ChromeDriver(options);

    // a new session token = a new IP, held by this browser for 30 minutes
    var token = Convert.ToHexString(RandomNumberGenerator.GetBytes(4)).ToLowerInvariant();
    var network = driver.Manage().Network;
    network.AddAuthenticationHandler(new NetworkAuthenticationHandler
    {
        UriMatcher = _ => true,
        Credentials = new PasswordCredentials("resi-lx_k3m9q2p7xa", $"YOUR_PASSWORD-session-{token}-time-30-country-us"),
    });
    await network.StartMonitoring();

    driver.Navigate().GoToUrl("https://api.ludaxproxy.com/whoami");
    Console.WriteLine($"{job} {driver.FindElement(By.TagName("body")).Text}");
    driver.Quit();
}
```

**Ruby** (`sticky.rb`)

```ruby
require "securerandom"
require "selenium-webdriver"

%w[account-1 account-2 account-3].each do |job|
  options = Selenium::WebDriver::Options.chrome(args: ["--proxy-server=http://gw.ludaxproxy.com:7777"])
  driver = Selenium::WebDriver.for(:chrome, options: options)
  begin
    # a new session token = a new IP, held by this browser for 30 minutes
    password = "YOUR_PASSWORD-session-#{SecureRandom.hex(4)}-time-30-country-us"
    driver.register(username: "resi-lx_k3m9q2p7xa", password: password)
    driver.get("https://api.ludaxproxy.com/whoami")
    puts "#{job} #{driver.find_element(tag_name: "body").text}"
  ensure
    driver.quit
  end
end
```

### Geo-targeting with a matching language and time zone

**Python** (`geo.py`)

```python
from selenium import webdriver
from ludax_login import with_proxy_login

options = webdriver.ChromeOptions()
options.add_argument("--proxy-server=http://gw.ludaxproxy.com:7777")
options.add_argument("--lang=de-DE")  # the browser's language
driver = webdriver.Chrome(options=options)
driver.execute_cdp_cmd("Emulation.setTimezoneOverride", {"timezoneId": "Europe/Berlin"})


def work(driver):
    driver.get("https://api.ludaxproxy.com/whoami")
    print(driver.find_element("tag name", "body").text)
    print(driver.execute_script("return [navigator.language, Intl.DateTimeFormat().resolvedOptions().timeZone]"))


try:
    # an IP in Munich for 30 minutes
    with_proxy_login(driver, "resi-lx_k3m9q2p7xa",
                     "YOUR_PASSWORD-session-muc01-time-30-country-de-state-by-city-munich", work)
finally:
    driver.quit()
```

**Java** (`Geo.java`)

```java
import java.util.Map;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.UsernameAndPassword;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;

public class Geo {
  public static void main(String[] args) {
    ChromeOptions options = new ChromeOptions();
    options.addArguments("--proxy-server=http://gw.ludaxproxy.com:7777", "--lang=de-DE");
    ChromeDriver driver = new ChromeDriver(options);
    try {
      driver.executeCdpCommand("Emulation.setTimezoneOverride", Map.of("timezoneId", "Europe/Berlin"));
      // an IP in Munich for 30 minutes
      driver.register(UsernameAndPassword.of("resi-lx_k3m9q2p7xa",
          "YOUR_PASSWORD-session-muc01-time-30-country-de-state-by-city-munich"));
      driver.get("https://api.ludaxproxy.com/whoami");
      System.out.println(driver.findElement(By.tagName("body")).getText());
      System.out.println(((JavascriptExecutor) driver).executeScript(
          "return navigator.language + ' ' + Intl.DateTimeFormat().resolvedOptions().timeZone"));
    } finally {
      driver.quit();
    }
  }
}
```

**JavaScript** (`geo.mjs`)

```javascript
import { Builder, By } from "selenium-webdriver";
import chrome from "selenium-webdriver/chrome.js";

const options = new chrome.Options().addArguments("--proxy-server=http://gw.ludaxproxy.com:7777", "--lang=de-DE");
const driver = await new Builder().forBrowser("chrome").setChromeOptions(options).build();
try {
  await driver.sendDevToolsCommand("Emulation.setTimezoneOverride", { timezoneId: "Europe/Berlin" });
  // an IP in Munich for 30 minutes
  await driver.register("resi-lx_k3m9q2p7xa", "YOUR_PASSWORD-session-muc01-time-30-country-de-state-by-city-munich",
    await driver.createCDPConnection("page"));
  await driver.get("https://api.ludaxproxy.com/whoami");
  console.log(await driver.findElement(By.css("body")).getText());
  console.log(await driver.executeScript("return [navigator.language, Intl.DateTimeFormat().resolvedOptions().timeZone]"));
} finally {
  await driver.quit();
}
```

**C#** (`Geo.cs`)

```csharp
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

var options = new ChromeOptions();
options.AddArguments("--proxy-server=http://gw.ludaxproxy.com:7777", "--lang=de-DE");
using var driver = new ChromeDriver(options);
driver.ExecuteCdpCommand("Emulation.setTimezoneOverride", new Dictionary<string, object> { ["timezoneId"] = "Europe/Berlin" });

// an IP in Munich for 30 minutes
var network = driver.Manage().Network;
network.AddAuthenticationHandler(new NetworkAuthenticationHandler
{
    UriMatcher = _ => true,
    Credentials = new PasswordCredentials("resi-lx_k3m9q2p7xa", "YOUR_PASSWORD-session-muc01-time-30-country-de-state-by-city-munich"),
});
await network.StartMonitoring();

driver.Navigate().GoToUrl("https://api.ludaxproxy.com/whoami");
Console.WriteLine(driver.FindElement(By.TagName("body")).Text);
Console.WriteLine(driver.ExecuteScript("return navigator.language + ' ' + Intl.DateTimeFormat().resolvedOptions().timeZone"));
driver.Quit();
```

**Ruby** (`geo.rb`)

```ruby
require "selenium-webdriver"

options = Selenium::WebDriver::Options.chrome(args: ["--proxy-server=http://gw.ludaxproxy.com:7777", "--lang=de-DE"])
driver = Selenium::WebDriver.for(:chrome, options: options)
begin
  driver.execute_cdp("Emulation.setTimezoneOverride", timezoneId: "Europe/Berlin")
  # an IP in Munich for 30 minutes
  driver.register(username: "resi-lx_k3m9q2p7xa",
                  password: "YOUR_PASSWORD-session-muc01-time-30-country-de-state-by-city-munich")
  driver.get("https://api.ludaxproxy.com/whoami")
  puts driver.find_element(tag_name: "body").text
  puts driver.execute_script("return navigator.language + ' ' + Intl.DateTimeFormat().resolvedOptions().timeZone")
ensure
  driver.quit
end
```

### Do not load images

**Python** (`save_data.py`)

```python
from selenium import webdriver
from ludax_login import with_proxy_login

options = webdriver.ChromeOptions()
options.add_argument("--proxy-server=http://gw.ludaxproxy.com:7777")
# images are never downloaded, so they never count against your GB
options.add_experimental_option("prefs", {"profile.managed_default_content_settings.images": 2})
driver = webdriver.Chrome(options=options)


def work(driver):
    driver.get("https://en.wikipedia.org/wiki/Proxy_server")
    print(driver.title)


try:
    with_proxy_login(driver, "resi-lx_k3m9q2p7xa", "YOUR_PASSWORD-session-wiki01-time-10-country-us", work)
finally:
    driver.quit()
```

**Java** (`SaveData.java`)

```java
import java.util.Map;
import org.openqa.selenium.HasAuthentication;
import org.openqa.selenium.UsernameAndPassword;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;

public class SaveData {
  public static void main(String[] args) {
    ChromeOptions options = new ChromeOptions();
    options.addArguments("--proxy-server=http://gw.ludaxproxy.com:7777");
    // images are never downloaded, so they never count against your GB
    options.setExperimentalOption("prefs", Map.of("profile.managed_default_content_settings.images", 2));
    WebDriver driver = new ChromeDriver(options);
    try {
      ((HasAuthentication) driver).register(UsernameAndPassword.of(
          "resi-lx_k3m9q2p7xa", "YOUR_PASSWORD-session-wiki01-time-10-country-us"));
      driver.get("https://en.wikipedia.org/wiki/Proxy_server");
      System.out.println(driver.getTitle());
    } finally {
      driver.quit();
    }
  }
}
```

**JavaScript** (`save_data.mjs`)

```javascript
import { Builder } from "selenium-webdriver";
import chrome from "selenium-webdriver/chrome.js";

const options = new chrome.Options()
  .addArguments("--proxy-server=http://gw.ludaxproxy.com:7777")
  // images are never downloaded, so they never count against your GB
  .setUserPreferences({ "profile.managed_default_content_settings.images": 2 });
const driver = await new Builder().forBrowser("chrome").setChromeOptions(options).build();
try {
  await driver.register("resi-lx_k3m9q2p7xa", "YOUR_PASSWORD-session-wiki01-time-10-country-us",
    await driver.createCDPConnection("page"));
  await driver.get("https://en.wikipedia.org/wiki/Proxy_server");
  console.log(await driver.getTitle());
} finally {
  await driver.quit();
}
```

**C#** (`SaveData.cs`)

```csharp
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

var options = new ChromeOptions();
options.AddArgument("--proxy-server=http://gw.ludaxproxy.com:7777");
// images are never downloaded, so they never count against your GB
options.AddUserProfilePreference("profile.managed_default_content_settings.images", 2);
using var driver = new ChromeDriver(options);

var network = driver.Manage().Network;
network.AddAuthenticationHandler(new NetworkAuthenticationHandler
{
    UriMatcher = _ => true,
    Credentials = new PasswordCredentials("resi-lx_k3m9q2p7xa", "YOUR_PASSWORD-session-wiki01-time-10-country-us"),
});
await network.StartMonitoring();

driver.Navigate().GoToUrl("https://en.wikipedia.org/wiki/Proxy_server");
Console.WriteLine(driver.Title);
driver.Quit();
```

**Ruby** (`save_data.rb`)

```ruby
require "selenium-webdriver"

options = Selenium::WebDriver::Options.chrome(args: ["--proxy-server=http://gw.ludaxproxy.com:7777"])
# images are never downloaded, so they never count against your GB
options.add_preference("profile.managed_default_content_settings.images", 2)
driver = Selenium::WebDriver.for(:chrome, options: options)
begin
  driver.register(username: "resi-lx_k3m9q2p7xa", password: "YOUR_PASSWORD-session-wiki01-time-10-country-us")
  driver.get("https://en.wikipedia.org/wiki/Proxy_server")
  puts driver.title
ensure
  driver.quit
end
```

### Retry a 502, stop on everything else

**Python** (`retry.py`)

```python
import time
from selenium import webdriver
from selenium.common.exceptions import WebDriverException
from ludax_login import with_proxy_login


def open_page(driver, url, tries=3):
    """Open a URL through Ludax: retry a dropped exit (502), stop at once on anything else."""
    for attempt in range(1, tries + 1):
        try:
            return driver.get(url)
        except WebDriverException as error:
            dropped = "ERR_TUNNEL_CONNECTION_FAILED" in str(error)
            if not dropped or attempt == tries:
                raise
            time.sleep(2 ** (attempt - 1))


options = webdriver.ChromeOptions()
options.add_argument("--proxy-server=http://gw.ludaxproxy.com:7777")
driver = webdriver.Chrome(options=options)


def work(driver):
    open_page(driver, "https://api.ludaxproxy.com/whoami")
    print(driver.find_element("tag name", "body").text)


try:
    with_proxy_login(driver, "resi-lx_k3m9q2p7xa", "YOUR_PASSWORD-country-us", work)
finally:
    driver.quit()
```

**Java** (`Retry.java`)

```java
import org.openqa.selenium.By;
import org.openqa.selenium.HasAuthentication;
import org.openqa.selenium.UsernameAndPassword;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;

public class Retry {
  // Open a URL through Ludax: retry a dropped exit (502), stop at once on anything else.
  static void open(WebDriver driver, String url, int tries) throws InterruptedException {
    for (int attempt = 1; ; attempt++) {
      try {
        driver.get(url);
        return;
      } catch (WebDriverException error) {
        boolean dropped = String.valueOf(error.getMessage()).contains("ERR_TUNNEL_CONNECTION_FAILED");
        if (!dropped || attempt == tries) throw error;
        Thread.sleep(1000L << (attempt - 1));
      }
    }
  }

  public static void main(String[] args) throws InterruptedException {
    ChromeOptions options = new ChromeOptions();
    options.addArguments("--proxy-server=http://gw.ludaxproxy.com:7777");
    WebDriver driver = new ChromeDriver(options);
    try {
      ((HasAuthentication) driver).register(
          UsernameAndPassword.of("resi-lx_k3m9q2p7xa", "YOUR_PASSWORD-country-us"));
      open(driver, "https://api.ludaxproxy.com/whoami", 3);
      System.out.println(driver.findElement(By.tagName("body")).getText());
    } finally {
      driver.quit();
    }
  }
}
```

**JavaScript** (`retry.mjs`)

```javascript
import { Builder, By } from "selenium-webdriver";
import chrome from "selenium-webdriver/chrome.js";

// Open a URL through Ludax: retry a dropped exit (502), stop at once on anything else.
async function open(driver, url, tries = 3) {
  for (let attempt = 1; ; attempt++) {
    try {
      return await driver.get(url);
    } catch (error) {
      const dropped = String(error.message).includes("ERR_TUNNEL_CONNECTION_FAILED");
      if (!dropped || attempt === tries) throw error;
      await new Promise((resolve) => setTimeout(resolve, 1000 * 2 ** (attempt - 1)));
    }
  }
}

const options = new chrome.Options().addArguments("--proxy-server=http://gw.ludaxproxy.com:7777");
const driver = await new Builder().forBrowser("chrome").setChromeOptions(options).build();
try {
  await driver.register("resi-lx_k3m9q2p7xa", "YOUR_PASSWORD-country-us", await driver.createCDPConnection("page"));
  await open(driver, "https://api.ludaxproxy.com/whoami");
  console.log(await driver.findElement(By.css("body")).getText());
} finally {
  await driver.quit();
}
```

**C#** (`Retry.cs`)

```csharp
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

var options = new ChromeOptions();
options.AddArgument("--proxy-server=http://gw.ludaxproxy.com:7777");
using var driver = new ChromeDriver(options);
var network = driver.Manage().Network;
network.AddAuthenticationHandler(new NetworkAuthenticationHandler
{
    UriMatcher = _ => true,
    Credentials = new PasswordCredentials("resi-lx_k3m9q2p7xa", "YOUR_PASSWORD-country-us"),
});
await network.StartMonitoring();

await Open(driver, "https://api.ludaxproxy.com/whoami");
Console.WriteLine(driver.FindElement(By.TagName("body")).Text);
driver.Quit();

// Open a URL through Ludax: retry a dropped exit (502), stop at once on anything else.
static async Task Open(IWebDriver driver, string url, int tries = 3)
{
    for (var attempt = 1; ; attempt++)
    {
        try
        {
            driver.Navigate().GoToUrl(url);
            return;
        }
        catch (WebDriverException error) when (
            error.Message.Contains("ERR_TUNNEL_CONNECTION_FAILED") && attempt < tries)
        {
            await Task.Delay(1000 * (1 << (attempt - 1)));
        }
    }
}
```

**Ruby** (`retry.rb`)

```ruby
require "selenium-webdriver"

# Open a URL through Ludax: retry a dropped exit (502), stop at once on anything else.
def open_page(driver, url, tries: 3)
  attempt = 0
  begin
    attempt += 1
    driver.get(url)
  rescue Selenium::WebDriver::Error::WebDriverError => e
    raise unless e.message.include?("ERR_TUNNEL_CONNECTION_FAILED") && attempt < tries
    sleep(2**(attempt - 1))
    retry
  end
end

options = Selenium::WebDriver::Options.chrome(args: ["--proxy-server=http://gw.ludaxproxy.com:7777"])
driver = Selenium::WebDriver.for(:chrome, options: options)
begin
  driver.register(username: "resi-lx_k3m9q2p7xa", password: "YOUR_PASSWORD-country-us")
  open_page(driver, "https://api.ludaxproxy.com/whoami")
  puts driver.find_element(tag_name: "body").text
ensure
  driver.quit
end
```

## Plans and help

- Prepaid, no subscription: 1 GB of Residential Proxies costs $0.99. The smallest plan is the test; there is no free trial. Every plan: https://ludaxproxy.com/pricing
- Credentials: dashboard, Generate (https://ludaxproxy.com/dashboard). A plan's password can be reset there.
- Full reference: https://ludaxproxy.com/docs. Whole site for AI: https://ludaxproxy.com/llms.txt
- Support: Telegram https://t.me/LudaxProxy, email support@ludaxproxy.com.
