Geonode Use Cases

How to Use Geonode Proxies with Python

Working Python examples for Geonode proxies with requests, httpx and aiohttp: environment variables, country targeting, rotating and sticky sessions, SOCKS5, concurrency, retries, block detection and common errors.

By Team of Monkeys Editorial Updated 4 min read Affiliate disclosure

This guide contains affiliate links to Geonode. If you buy through them we may earn a commission, at no extra cost to you.

Setup

Generate an endpoint in the Geonode dashboard (product, rotating or sticky session, location, host:port:username:password format) and export the values:

bash
export GEONODE_HOST="<host>"
export GEONODE_PORT="<port>"
export GEONODE_USER="<username>"
export GEONODE_PASS="<password>"

Keep credentials out of code and out of version control. A small helper builds proxy URLs everywhere else:

python
import os
from urllib.parse import quote

def geonode_url(country=None, scheme="http"):
    user = os.environ["GEONODE_USER"] + (f"-country-{country}" if country else "")
    pw = quote(os.environ["GEONODE_PASS"], safe="")
    return f"{scheme}://{user}:{pw}@{os.environ['GEONODE_HOST']}:{os.environ['GEONODE_PORT']}"

The -country- suffix follows the pattern in Geonode's documentation (for example -country-jp); use your dashboard's exact format. URL-encoding the password avoids errors when it contains characters such as @ or :.

requests

python
import requests

proxy = geonode_url("us")
r = requests.get("https://api.ipify.org", proxies={"http": proxy, "https": proxy}, timeout=30)
print(r.text)

For several requests that should share cookies and an IP (with a sticky endpoint), use a Session:

python
s = requests.Session()
s.proxies = {"http": proxy, "https": proxy}
s.get("https://example.com/", timeout=30)
s.get("https://example.com/page/2", timeout=30)

See Python requests proxies.

httpx

python
import httpx

with httpx.Client(proxy=geonode_url("gb"), timeout=30) as client:
    print(client.get("https://api.ipify.org").text)

httpx also supports HTTP/2 and async clients with the same proxy option.

aiohttp for concurrency

python
import asyncio
import aiohttp

async def fetch(session, url, sem):
    async with sem:
        async with session.get(url, proxy=geonode_url("us"), timeout=aiohttp.ClientTimeout(total=30)) as r:
            return r.status, await r.text()

async def main(urls):
    sem = asyncio.Semaphore(20)
    async with aiohttp.ClientSession() as session:
        return await asyncio.gather(*(fetch(session, u, sem) for u in urls), return_exceptions=True)

Cap concurrency per target domain to stay polite and avoid blocks.

SOCKS5

Geonode lists SOCKS5 support for residential proxies. With requests, install the SOCKS extra (pip install "requests[socks]") and use the socks5h scheme so DNS is resolved through the proxy:

python
proxy = geonode_url("de", scheme="socks5h")
requests.get("https://api.ipify.org", proxies={"http": proxy, "https": proxy}, timeout=30)

SOCKS5 may use a different port from HTTP; check the dashboard. See SOCKS5 proxies.

Proxy tip: Before scaling, run a short pilot on your real targets with Geonode and record success rate, latency and GB per result. Our our complete Geonode guide explains which Geonode product to start with.

Retries and block detection

Check for real content, not just status 200, and retry with a new IP:

python
import time

def get_with_retry(url, marker, attempts=3):
    for n in range(attempts):
        p = geonode_url("us")
        try:
            r = requests.get(url, proxies={"http": p, "https": p}, timeout=30)
            if r.ok and marker in r.text:
                return r
        except requests.RequestException:
            pass
        time.sleep(1 + n * 2)
    return None

With a rotating endpoint, each new connection gets a new exit. Disable connection reuse (use fresh requests rather than one session) when you want a new IP per attempt.

Common errors

ErrorMeaningFix
407 Proxy Authentication RequiredCredentials or username format wrongRe-copy from dashboard; URL-encode the password
ProxyError / connection refusedWrong host or port, or blocked outbound portCheck endpoint; test with cURL
SSLError through proxyCorporate interception or wrong schemeUse http:// for the proxy URL; don't disable verification
ReadTimeoutSlow exitRaise timeout moderately; retry with a new IP
InvalidSchema for SOCKSSOCKS support not installedInstall requests[socks]

See common proxy errors.

Picking a Geonode product for your Python job

The Python examples above work with any Geonode product; only the endpoint changes. Choose based on the target and the shape of the job.

Python jobGeonode productNotes
Data from public portals and lenient sitesRotating datacenterCheapest per GB; test first
Scraping protected retailers, marketplaces or search pagesRotating residentialNew connection per request for a new exit
Logged-in or multi-page flowsSticky residentialOne Session per flow
A fixed IP for an API partner's allowlistISP proxyStatic IP, unmetered bandwidth
JavaScript-heavy pagesPlaywright for Python with residential, or the Scraper APISee Geonode with Playwright

Many Python projects route by domain: a dictionary mapping domains to "datacenter" or "residential", consulted by the helper that builds proxy URLs. Start every new domain on datacenter, measure success on real content, and promote it to residential only if it fails. That habit keeps per-GB costs low.

A checklist for Python proxy code in production

  • Timeouts on every request. Without them, a stalled exit can hang a worker indefinitely.
  • Retries with a fresh IP and backoff, capped at two or three attempts.
  • Content checks to catch block pages that return status 200.
  • Per-domain concurrency limits, especially with aiohttp or httpx async clients, which make it easy to send far more requests than a site tolerates.
  • Connection reuse on purpose: reuse a Session for sticky flows, avoid it when you want a new exit per request.
  • Secrets outside the code, loaded from environment variables or a secrets manager.
  • Structured logs with domain, outcome, status, latency and bytes, so you can see success rates and bandwidth per target.
  • A smoke test that requests an IP echo endpoint through each configured product at startup and fails fast if credentials are wrong.

For framework-level crawling with built-in throttling and retries, see Geonode with Scrapy. For a wider view of scraping with Geonode, see Geonode for web scraping.

Testing your setup

A quick self-test catches most configuration mistakes before they reach production:

  1. Request an IP echo service three times through a rotating endpoint; expect three different IPs.
  2. Request it three times through a sticky endpoint with a Session; expect the same IP.
  3. Request a geolocation service through a country-targeted endpoint; expect the right country.
  4. Request your real target once and check for expected content.

Wrap these in a small script that exits with an error if any check fails, and run it at deploy time and in CI with a test sub-user. When something breaks later, run the same script first: it tells you within seconds whether the problem is credentials, targeting, sessions or the target itself. For command-line checks, see Geonode with cURL.

FAQ

How do I rotate IPs with requests?

Use a rotating Geonode endpoint and new connections per request. A shared Session reuses connections and may keep the same exit.

How do I keep the same IP across requests?

Use a sticky endpoint and a Session.

Why does my password break the proxy URL?

Special characters must be URL-encoded. Use urllib.parse.quote.

Which library should I use?

requests for simple scripts, httpx for modern sync or async code with HTTP/2, aiohttp for high-concurrency async jobs.

Affiliate disclosure: Team of Monkeys is a Geonode affiliate. Links and banners marked as sponsored, and links to Geonode in the text, use our referral link, and we may earn a commission if you buy through them, at no extra cost to you. Our explanations and comparisons are written to be useful whichever provider you choose.

Editorial note: Proxy providers change their pools, features and prices often, so treat any figures here as typical ranges at the time of writing and confirm current terms with the provider before you buy.