How to Use AdsPower with Selenium: Setup and Examples

By Anonymous☉ 3797 Views

Take a Quick Look

Connect AdsPower to Selenium via the Local API, launch isolated anti-detect profiles, and automate multi-account workflows with Python code examples.

🔥 Limited-Time Offer! Save extra 10% off on your first monthly plan with code: Anitdetect10

How to Use AdsPower with Selenium: Setup and Examples

AdsPower gives each browser profile an isolated fingerprint, and Selenium gives you code that drives a browser. Put them together and you can automate dozens of accounts that each look like a separate real device. This guide explains how the two tools connect, walks through the setup step by step, and shows working Python examples you can adapt.

Why combine AdsPower with Selenium

Selenium product interface

Selenium product interface.

Selenium on its own launches a normal browser. Every session shares the same cookies, canvas fingerprint, WebGL renderer, and user agent, so platforms can link your accounts together. AdsPower solves that by creating isolated browser environments with unique fingerprints (Canvas, WebGL, User Agent, IP, and more) and proxy assignment per profile.

The combination gives you:

  • Fingerprint isolation per automation run. Each Selenium session attaches to a different AdsPower profile, so no two runs look like the same device.
  • Proxy control. Traffic leaves through the proxy bound to that profile, not your local IP.
  • Scale without rewriting scripts. The same Selenium code works across hundreds of profiles by changing one ID.
  • State that persists. Cookies and logins stay inside the profile, so you authenticate once and reuse the session.

This is the pattern behind multi-account e-commerce operations, social media marketing at scale, affiliate work, and web scraping where each request should look like a distinct visitor.

How the connection actually works

Selenium product interface

Selenium product interface.

AdsPower runs a local service on your machine. Selenium does not launch Chrome itself; instead, it asks AdsPower to start a profile and then attaches to the already-running browser through a debug interface.

The flow is:

  1. Your script calls the AdsPower Local API to start a profile.
  2. AdsPower launches that profile's browser with its fingerprint and proxy.
  3. The API returns a WebDriver path and a debugger address (the selenium value inside ws).
  4. Selenium connects to that address using debuggerAddress.
  5. Your script drives the page normally.
  6. When finished, you quit the driver and call the stop endpoint.

Two details matter here. First, the WebDriver returned by the API must match the browser core version of that profile, which is why you should use the path AdsPower gives you rather than a driver you downloaded separately. Second, the Local API listens on http://local.adspower.net:50325 (or http://127.0.0.1:50325), so nothing needs to be exposed to the internet.

Prerequisites

Before writing code, confirm you have:

  • AdsPower installed and at least one profile created. Note its profile ID (also called user_id).
  • The Local API enabled in AdsPower settings.
  • Python 3.8 or newer with pip.
  • The Selenium package installed.
  • An API key if your AdsPower version requires authorization headers.

Install the dependencies:

pip install selenium requests

Step 1: Start a profile with the Local API

The start endpoint is a GET request:

GET http://local.adspower.net:50325/api/v1/browser/start?user_id=<PROFILE_ID>

Useful optional parameters include headless=1 for background runs, open_tabs=1 to skip restoring previous tabs, ip_tab=0 to suppress the IP detection page, and launch_args to pass Chrome flags such as --disable-notifications. A successful response looks like this:

{
  "code": 0,
  "data": {
    "ws": {
      "selenium": "127.0.0.1:xxxx",
      "puppeteer": "ws://127.0.0.1:xxxx/devtools/browser/xxxxxx"
    },
    "debug_port": "xxxx",
    "webdriver": "C:\\xxxx\\chromedriver.exe"
  },
  "msg": "success"
}

If code is not 0, the profile did not launch. The msg field usually tells you whether the profile ID is wrong or the Local API is not running.

Step 2: Attach Selenium to the running browser

Selenium product interface

Selenium product interface.

With Selenium 4.18 and newer, pass the returned WebDriver path to a Service object and set debuggerAddress to the selenium value:

import time
import requests
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service
import sys

ads_id = "your_profile_id"
api_key = "your_api_key_here"

open_url = f"http://local.adspower.net:50325/api/v1/browser/start?user_id={ads_id}"
close_url = f"http://local.adspower.net:50325/api/v1/browser/stop?user_id={ads_id}"
headers = {"Authorization": f"Bearer {api_key}"}

resp = requests.get(open_url, headers=headers).json()
if resp["code"] != 0:
    print(resp["msg"])
    sys.exit("Check the profile ID and Local API status")

chrome_driver = resp["data"]["webdriver"]
service = Service(executable_path=chrome_driver)
options = Options()
options.add_experimental_option("debuggerAddress", resp["data"]["ws"]["selenium"])

driver = webdriver.Chrome(service=service, options=options)
print(driver.title)
driver.get("https://www.browserscan.net/")
time.sleep(5)

driver.quit()
requests.get(close_url, headers=headers)

On older Selenium 3.x builds the same idea applies, but you pass the driver path positionally instead of through Service. If you are still on 3.x, upgrading is the simpler fix.

Opening a fingerprint test page first is a good habit. It confirms the profile is presenting the fingerprint and IP you configured before you run any real task.

Step 3: Build a reusable helper

Hardcoding this in every script gets messy. Wrap it in a context manager so profiles open and close cleanly, even when a task fails:

from contextlib import contextmanager

BASE = "http://local.adspower.net:50325"

@contextmanager
def adspower_profile(profile_id, api_key=""):
    headers = {"Authorization": f"Bearer {api_key}"} if api_key else {}
    start = requests.get(
        f"{BASE}/api/v1/browser/start",
        params={"user_id": profile_id, "open_tabs": 1, "ip_tab": 0},
        headers=headers,
    ).json()
    if start["code"] != 0:
        raise RuntimeError(start["msg"])

    data = start["data"]
    options = Options()
    options.add_experimental_option("debuggerAddress", data["ws"]["selenium"])
    driver = webdriver.Chrome(
        service=Service(executable_path=data["webdriver"]), options=options
    )
    try:
        yield driver
    finally:
        driver.quit()
        requests.get(
            f"{BASE}/api/v1/browser/stop",
            params={"user_id": profile_id},
            headers=headers,
        )

Now any task becomes three lines:

with adspower_profile("profile_id_here", api_key) as driver:
    driver.get("https://example.com/dashboard")
    print(driver.title)

Practical example: checking accounts across profiles

A common task is verifying that a batch of accounts still logs in correctly. Loop over profile IDs, attach Selenium to each, and record the result:

profiles = ["id_001", "id_002", "id_003"]
results = {}

for pid in profiles:
    try:
        with adspower_profile(pid, api_key) as driver:
            driver.get("https://example.com/login")
            driver.find_element("id", "email").send_keys("user@example.com")
            driver.find_element("id", "password").send_keys("secret")
            driver.find_element("css selector", "button[type=submit]").click()
            results[pid] = "ok" if "dashboard" in driver.current_url else "check"
    except Exception as exc:
        results[pid] = f"error: {exc}"

print(results)

Because each profile keeps its own cookies, a profile that logged in yesterday is still logged in today, and you can skip the login step entirely.

If your work is scraping rather than account management, the same helper applies, but pair it with a scraping API or rotating proxy setup. For a related pattern, see How to Use AdsPower with Scrapestack: Setup & Workflow.

Practical example: running profiles in parallel

Sequential runs are slow when you have many profiles. Since each profile is an independent browser, you can run several at once with threads:

from concurrent.futures import ThreadPoolExecutor

def scrape(pid):
    with adspower_profile(pid, api_key) as driver:
        driver.get("https://example.com/data")
        return pid, driver.title

with ThreadPoolExecutor(max_workers=4) as pool:
    for pid, title in pool.map(scrape, profiles):
        print(pid, title)

Keep the worker count modest. Each running profile consumes real memory, and heavy parallelism on one machine will slow everything down or trigger timeouts. Four to eight concurrent profiles is a reasonable starting range on a typical workstation.

Common problems and fixes

The profile starts but Selenium cannot connect. The debuggerAddress value must be the selenium field, not the puppeteer WebSocket URL. They are different interfaces.

Session not created or driver version mismatch. Use the webdriver path returned by the API. It is matched to that profile's browser core. A manually downloaded driver often is not.

The API returns a non-zero code. Check that the profile ID is exact, that the profile is not already open, and that the Local API is enabled in AdsPower settings.

The browser opens but the page shows the wrong location. The proxy is attached to the profile, not to your Selenium code. Fix it in the profile's proxy settings and confirm with a fingerprint or IP check page.

Scripts hang on quit. Always call driver.quit() and then the stop endpoint. Leaving profiles open blocks the next run for that same profile.

Headless mode behaves differently. Some sites detect headless browsers. If a task fails only in headless mode, test it with a visible window first to isolate the cause.

AdsPower versus plain Selenium: when each fits

Selenium product interface

Selenium product interface.

Scenario Plain Selenium AdsPower + Selenium
Testing your own web app Good fit Unnecessary overhead
One account, one machine Good fit Optional
Many accounts on one device Fingerprints collide Isolated profiles per account
Proxy per account Manual configuration Bound to the profile
Persistent logins across runs Fragile Stored inside the profile
Team access to the same profiles Not supported Shared workspace

If your automation only ever touches one account, plain Selenium is simpler. The moment account association becomes a risk, the anti-detect layer earns its place. If you are comparing anti-detect options before committing, this AdsPower vs Incogniton vs BitBrowser comparison covers fingerprint handling, automation support, and pricing.

Scaling beyond one machine

When a single workstation is not enough, Selenium Grid distributes sessions across multiple machines. The same idea works here: each Grid node runs its own AdsPower instance with its own set of profiles, and your script routes work to the right node. Keep profile-to-node mapping explicit so a profile is never opened twice at the same time.

The AdsPower Local API documentation covers the full parameter list for the start endpoint, including headless mode, launch arguments, and cache clearing. The official code samples page includes Python, JavaScript, and Java versions for both Chrome and Firefox, and the open browser endpoint reference documents every query parameter and return field.

Related reading

Sources and further reading

FAQ

Does AdsPower work with Selenium 4? Yes. Selenium 4.18 and newer work with the Service object shown above. Selenium 3.141 also works with a slightly different driver setup.

Do I need an API key? Some AdsPower versions require a Bearer token in the request headers. If your Local API accepts unauthenticated requests, you can omit the header.

Can I run AdsPower profiles headless with Selenium? Yes, pass headless=1 to the start endpoint. Test carefully, because some sites treat headless browsers differently.

How many profiles can run at once? It depends on your machine's memory and CPU. Each profile is a full browser instance. Start with four concurrent profiles and increase gradually.

Does Selenium see the profile's proxy? Yes. The proxy is configured on the profile, so all traffic from that browser session exits through it without any Selenium-side proxy settings.

Can I use Firefox instead of Chrome? AdsPower supports Firefox profiles with Selenium, but it requires a recent AdsPower patch and Firefox 123 or newer. Chrome is the more common and better-documented path.

What about Puppeteer or Playwright? The same start endpoint returns a puppeteer WebSocket URL that Playwright and Puppeteer can connect to over CDP. If your stack is JavaScript-based, that route works equally well.

Conclusion

AdsPower and Selenium split the work cleanly: AdsPower handles identity, fingerprints, and proxies, while Selenium handles the actions your script performs. The integration comes down to one pattern, start the profile through the Local API, read the returned WebDriver path and debugger address, and attach Selenium to the running browser.

Once that helper function exists, scaling is just a loop or a thread pool. Add profile-level isolation, keep your worker count sane, and always close profiles when a task finishes. If you also manage storefronts or social accounts manually alongside your automation, a guide like How to Use AdsPower with Shopify: Multi-Store Setup Guide shows how the same profile structure supports day-to-day operations.

AI INSIGHTS

Need a Quick Summary? Ask AI