JustBrowser
Tutorials11 min read

Cookie Warmup Script for Antidetect Profiles: 50-Site Automation

JustBrowser Platform Team·
cookie-warmupprofile-agingbrowser-automationantidetect-scriptingaccount-maturitybuildinpublicsaasstudioaiworkforcebuildwithclaude

Here's a scenario that catches a lot of people out: a fresh profile sails through every fingerprint test — CreepJS, Pixelscan, IPHey, all clean — gets a residential proxy, logs into a web app you're testing, and gets challenged with extra verification within the hour anyway. Technically perfect, and still treated as unusual.

The reason is almost always the same one. The profile is empty. Zero cookies. No browsing history. No localStorage from YouTube or Reddit or Google. From the site's perspective, this "user" never visited a single website before showing up at the login page. That's not how humans work, and risk systems know it. (If you're running ads through these profiles, understanding click fraud patterns becomes equally important.)

Fingerprint tweaking gets all the attention. Cookie history gets none of it — and it's the part that matters more.

The fix isn't more fingerprint tweaking. It's giving the profile a realistic, populated state before you use it for testing or verification work.

What We're Building

By the end of this tutorial, you'll have a working Python script that:

  1. Launches a JustBrowser profile via REST API
  2. Visits 50+ popular websites with realistic browsing patterns
  3. Scrolls, pauses, lets ads load — the stuff real humans do
  4. Closes the browser with cookies saved to the profile
  5. Can run unattended via cron or scheduled tasks

The script handles the warm-up. You handle the patience, and you handle each platform's rules: this tutorial is for profiles on accounts you're allowed to hold, not for working around a platform's limits on accounts or its enforcement. (The waiting is the hard part, honestly.)

Prerequisites

  • Python 3.9+ with requests and either playwright or selenium installed
  • JustBrowser ($9.99/mo, the one plan) — REST API automation needs a subscription, and the 7-day trial includes the API in full, so you can get the script working before the first charge
  • A configured profile — fingerprint set up, proxy assigned, timezone matching your proxy location
  • 20-30 minutes per profile — warm-up isn't instant

If you're not familiar with connecting automation frameworks to JustBrowser, the Playwright/Puppeteer integration guide and Selenium tutorial cover the connection plumbing. This tutorial assumes you've got that working and focuses on the warm-up logic itself.

Step 1: Define Your Target Site List

Here's a starter list. These are common sites — the kind everyone visits — mixed with some that set tracking cookies aggressively (which is actually what we want):

WARMUP_SITES = [
    # Search & video (hit these first — everyone has Google/YouTube cookies)
    "https://www.google.com", "https://www.youtube.com", "https://www.bing.com",
    # Social
    "https://www.facebook.com", "https://www.instagram.com", "https://twitter.com",
    "https://www.linkedin.com", "https://www.reddit.com", "https://www.tiktok.com",
    # Shopping
    "https://www.amazon.com", "https://www.ebay.com", "https://www.walmart.com",
    "https://www.etsy.com", "https://www.aliexpress.com",
    # News
    "https://www.cnn.com", "https://www.bbc.com", "https://www.nytimes.com",
    "https://news.ycombinator.com",
    # Tech
    "https://www.github.com", "https://stackoverflow.com", "https://www.medium.com",
    # Reference & utilities
    "https://www.wikipedia.org", "https://www.weather.com", "https://maps.google.com",
    # Streaming
    "https://www.twitch.tv", "https://www.netflix.com", "https://www.spotify.com",
    # Finance
    "https://www.paypal.com", "https://finance.yahoo.com",
    # Travel
    "https://www.booking.com", "https://www.airbnb.com",
    # Ad networks (drop tracking cookies that make a browser look "normal")
    "https://www.doubleclick.net", "https://www.googleadservices.com",
    # Add 15-20 more as needed...
]

That's ~35 sites — extend to 50+ with more news, shopping, entertainment. Hitting ad networks sounds counterintuitive, but a browser with zero third-party cookies looks unusual to systems trained on real user data, which skews QA and ad-verification results. (Yes, I'm telling you to actively collect tracking cookies. The irony isn't lost on me.)

Step 2: Build the Warm-Up Script

Here's the full script using Playwright — the Selenium variant follows in Step 4.

import requests
import random
import time
from playwright.sync_api import sync_playwright

API_BASE = "http://127.0.0.1:36542/api/v1"
HEADERS = {"Authorization": "Bearer <token from the app's API/AI tab>"}

WARMUP_SITES = [
    # ... your site list from above
]

def launch_profile(profile_id: str) -> str:
    """Start profile, return its CDP URL."""
    response = requests.post(
        f"{API_BASE}/profiles/{profile_id}/start",
        json={"headless": False},
        headers=HEADERS
    )
    response.raise_for_status()
    return response.json()["data"]["cdp_url"]


def stop_profile(profile_id: str):
    """Stop profile and save cookies."""
    requests.post(f"{API_BASE}/profiles/{profile_id}/stop", headers=HEADERS)


def human_scroll(page, duration_seconds: int = 3):
    """Scroll like a human — variable speed, occasional pauses."""
    end_time = time.time() + duration_seconds
    while time.time() < end_time:
        scroll_amount = random.randint(100, 400)
        page.mouse.wheel(0, scroll_amount)
        time.sleep(random.uniform(0.3, 0.8))

        # Occasional pause like reading
        if random.random() < 0.2:
            time.sleep(random.uniform(1.0, 2.5))


def visit_site(page, url: str):
    """Visit a site with realistic behavior."""
    try:
        # Navigate with timeout
        page.goto(url, timeout=15000, wait_until="domcontentloaded")

        # Wait for some content to load
        time.sleep(random.uniform(2, 4))

        # Scroll through the page
        human_scroll(page, duration_seconds=random.randint(3, 8))

        # Maybe click something (25% chance)
        if random.random() < 0.25:
            links = page.query_selector_all("a[href]")
            if links and len(links) > 5:
                # Pick a random visible link
                link = random.choice(links[3:min(10, len(links))])
                try:
                    link.click(timeout=3000)
                    time.sleep(random.uniform(2, 4))
                    human_scroll(page, duration_seconds=2)
                    page.go_back()
                except:
                    pass  # Link might be dead or blocked

        # Pause before next site
        time.sleep(random.uniform(1, 3))

    except Exception as e:
        print(f"  Failed {url}: {e}")


def warmup_profile(profile_id: str, site_count: int = 50):
    """Run full warm-up routine on a profile."""

    print(f"Launching profile {profile_id}...")
    cdp_url = launch_profile(profile_id)

    # Give browser time to fully initialize
    time.sleep(3)

    with sync_playwright() as p:
        browser = p.chromium.connect_over_cdp(cdp_url)
        context = browser.contexts[0]
        page = context.pages[0] if context.pages else context.new_page()

        # Randomize site order
        sites = random.sample(WARMUP_SITES, min(site_count, len(WARMUP_SITES)))

        print(f"Visiting {len(sites)} sites...")
        for i, url in enumerate(sites):
            print(f"  [{i+1}/{len(sites)}] {url}")
            visit_site(page, url)

        # Final scroll on last page
        human_scroll(page, duration_seconds=5)

        browser.close()

    # Stop profile (saves cookies)
    stop_profile(profile_id)
    print(f"Warm-up complete. Cookies saved.")


if __name__ == "__main__":
    import sys
    if len(sys.argv) < 2:
        print("Usage: python warmup.py <profile_id>")
        sys.exit(1)

    warmup_profile(sys.argv[1])

Step 3: Why These Patterns Matter

It's tempting to skip this section because "it's just scrolling." Don't — this is where most warm-up scripts fail.

Randomized scroll distances. Real users don't scroll in perfect 300px increments. The human_scroll function varies 100-400px per wheel event with pauses. Detection services track scroll entropy — and yes, they really do.

Variable dwell time. A bot spending exactly 2.0 seconds on every page is obvious. A human who spends 3s, 7s, 2s, 9s looks... human.

Occasional clicks. 25% of visits include a link click, wait, scroll, go back. Mimics real browsing and triggers additional cookie-setting events.

Site order randomization. Every run shuffles the list. Weekly maintenance runs look different each time.

Hover events are deliberately left out of this script. They add real runtime without enough of a detection-score payoff to justify it — not every "realistic" signal is worth the time it costs.

Step 4: Selenium Variant

If your stack is Selenium-based, the pattern is identical. Replace page.mouse.wheel() with driver.execute_script("window.scrollBy(0, N)") and use the cdp_url from the start response (or the connection details from GET /profiles/{id}/selenium) instead of a WebSocket endpoint. The Selenium tutorial has the full connection code — just drop the human_scroll and visit_site functions from above into that setup.

Step 5: Scheduling Maintenance

A profile warmed up once and never touched drifts from realistic state within weeks. Session cookies expire, ad tracking refreshes, the cookie jar slowly empties.

For ongoing profiles, schedule weekly maintenance:

macOS cron:

# Run every Sunday at 3am
0 3 * * 0 /usr/bin/python3 /path/to/warmup.py profile-001
0 3 * * 0 /usr/bin/python3 /path/to/warmup.py profile-002

Windows Task Scheduler: Create a task that triggers weekly, runs python warmup.py profile-001.

You don't need to hit all 50 sites every week. 15-20 is enough for maintenance. Modify the script to take a --quick flag that limits to 20 sites with shorter dwell times.

If you're running paid ad campaigns through these profiles and need to track conversions across your isolated browsers, JustAnalytics handles attribution without leaking data between profiles. And if you're worried about click fraud eating your budget while you're busy warming up profiles, ClickzProtect monitors for that on the ad platform side.

Common Errors and Fixes

TimeoutError: page.goto timed out

Cause: Site is slow, blocked your IP, or requires JavaScript that isn't finishing.

Fix: The script already has a 15-second timeout and catches exceptions. If a specific site keeps failing, remove it from your list. Some sites (especially banking sites) actively block automated browsers regardless of fingerprint quality. That's fine — skip them.

Browser crashes during warm-up

Cause: Memory. Each Chromium instance eats 300-600MB. Running multiple profiles simultaneously compounds this.

Fix: Run profiles sequentially, not in parallel. If you need to warm up 20 profiles, queue them. One at a time, 30 minutes each. Yes, that's 10 hours. Annoying? Absolutely. Schedule it overnight and go do something else with your life.

Cookies not persisting after warm-up

Cause: You're quitting the browser without calling the stop endpoint, so the session never closes cleanly.

Fix: Always call stop_profile() after the browser closes. This triggers JustBrowser's save routine. Cookies persist in the profile automatically once the browser is stopped cleanly — there is no setting to enable.

Profile still challenged after warm-up

Cause: Warm-up fixes cookie history but doesn't fix fingerprint issues, IP reputation, or behavioral tells during actual use.

Fix: Test fingerprint separately using CreepJS or Pixelscan. Check IP reputation on IPQualityScore. And honestly? The ISP proxy setup guide probably matters more than an extra 10 sites in your warm-up list. This one's frustrating because you can do everything right on the cookie side and still get challenged for something unrelated. A warm profile with a datacenter IP still gets extra verification. A cold profile with a clean residential IP sometimes doesn't. Do both. If a platform restricts or suspends an account, use its official appeal route; a warm-up script is not a way around that.

Next Steps

Profile aging. A 3-month-old profile with continuous cookie warmup activity gives more representative test results than a cold profile. Build history early, maintain it weekly. For tracking conversions across isolated profiles without data leakage, see the JustAnalytics attribution setup.

Platform-specific behavior. After generic warm-up, add sessions for the platforms you test against, using accounts you're entitled to use under that platform's terms.

Proxy consistency. Every warm-up session should use the same proxy the account will use. Covered in the timezone and geolocation guide.

The script gives you the mechanics. Patience gives you the results. 48 hours of waiting beats 48 hours of re-running invalid tests. That's the whole trade-off, and it's not a close call.

FAQ

How long should I warm up a profile before using it for real accounts?

At minimum, 24-48 hours between creation and the first login to a sensitive account you are permitted to use. But time alone isn't enough — you need activity. A 2-week-old profile with zero cookies looks weirder than a 2-day-old profile with 50 sites visited, ads loaded, and realistic scroll patterns. The script in this post builds history in about 30 minutes per profile, then you wait a day before touching any account that matters. Warm-up is not a substitute for following each platform's terms.

You can, but some detection services treat headless execution as automated. JustBrowser patches most headless signals, but if you're testing against high-security targets, run headed. The resource cost is higher but results are more representative. For bulk warm-up across many profiles, run 3-4 headed instances sequentially rather than 10+ headless in parallel.

Does warm-up order matter — should I visit certain sites first?

Start with Google and YouTube. These are the two most commonly visited sites globally, so a profile with Google cookies but no YouTube cookies looks off. After that, vary the order randomly. Real humans don't visit sites in alphabetical order. The script randomizes site order per run, which also means you can re-run it weekly for ongoing profile maintenance.

How often should I re-warm profiles that are already in use?

Once a week for active profiles. Daily if the profile is business-critical. The goal is continuous, realistic activity — not a one-time setup. A profile that logs into the same web app daily but visits zero other sites looks automated. Add 5-10 site visits weekly, scroll through some content, let ads load. The script can run on a schedule via cron or task scheduler.


Try JustBrowser

Native Chromium antidetect browser — not extension-based. Real C++ engine patches at the canvas / WebGL / audio / font / screen layer, so 40+ identity parameters are genuine, not faked. REST API for Playwright, Puppeteer, Selenium. $9.99/month or $99.99/year. 7-day free trial, card required — cancel any time in the seven days and you are not charged. Unlimited profiles.

Get started → · How it differs from Multilogin / GoLogin / AdsPower

Ready to manage multiple accounts?

Seven days free, then $9.99/month — one plan, everything included.

We'd like to use Google Analytics, a Google service, to understand how our website is used. It sets two cookies in your browser and runs only if you click Accept. You can change your choice at any time with Cookie settings. Cookie Policy

Sign-in cookies and the cookie that remembers this choice are always on; the website needs them to work.

Google Analytics, a Google service, helps us understand how our website is used. It sets two cookies, _ga and _ga_TVZHQ99TZW. It is now onoff in this browser. If your browser sends a Global Privacy Control or Do Not Track signal, it stays off. Cookie Policy