Quick answer
How do I use proxies in Python?
Pass a proxy URL such as http://USERNAME-country-ae:[email protected]:7777 to your HTTP client. Nameless Proxy, a privacy-first, no-KYC proxy provider, works with requests, httpx, aiohttp and Scrapy, and with socks5h:// on port 7778. Targeting lives in the username. Residential traffic starts at $0.53/GB. No KYC — no ID, no selfie, no documents. Pay in crypto.
Python setup at a glance
| Proxy URL | http://USER-country-xx:[email protected]:7777 |
|---|---|
| SOCKS5 | socks5h://…:7778 with requests[socks] |
| requests | proxies={"http": url, "https": url} |
| httpx 0.26+ | httpx.Client(proxy=url) and httpx.AsyncClient(proxy=url) |
| aiohttp | session.get(url, proxy=proxy_url) (HTTP proxies) |
| Scrapy | request.meta["proxy"], set by a downloader middleware |
| Sticky IP | Add -session-{id}-ttl-{minutes} after the city, for up to 60 minutes |
How do I use a proxy with requests?
Give requests the same proxy URL for both http and https keys. HTTPS targets go through a CONNECT tunnel, so the TLS connection stays between your script and the site. Always set a timeout.
# pip install requests
import requests
USERNAME = "USERNAME" # base proxy username from the client area
PASSWORD = "PASSWORD" # proxy password (not your account password)
HOST = "gw.namelessproxy.com"
HTTP_PORT = 7777
SOCKS_PORT = 7778
proxy = f"http://{USERNAME}-country-ae:{PASSWORD}@{HOST}:{HTTP_PORT}"
proxies = {"http": proxy, "https": proxy}
r = requests.get("https://api.ipify.org?format=json", proxies=proxies, timeout=30)
print(r.json()) # {'ip': '...'}How do I build targeted and sticky proxy URLs?
Use one helper for every library. The username follows USERNAME-country-{cc}-city-{city}-session-{id}-ttl-{minutes}, so the helper adds parts in that order: country, then city, then session and TTL. Without a session you get a rotating IP; with one, the IP stays the same while the TTL lasts.
import uuid
def proxy_url(country, city=None, session=None, ttl=30, scheme="http"):
"""Build a gateway URL. Targeting lives in the username, in this order:
country -> city -> session -> ttl."""
user = f"{USERNAME}-country-{country.lower()}"
if city:
user += f"-city-{city.lower().replace(' ', '_')}"
if session:
user += f"-session-{session}-ttl-{ttl}"
port = SOCKS_PORT if scheme.startswith("socks") else HTTP_PORT
return f"{scheme}://{user}:{PASSWORD}@{HOST}:{port}"
def new_session():
"""A fresh session ID = a fresh sticky IP."""
return uuid.uuid4().hex[:10]
# Rotating IP in Egypt, and a sticky IP in Abu Dhabi for 30 minutes
rotating = proxy_url("eg")
sticky = proxy_url("ae", city="Abu Dhabi", session=new_session(), ttl=30)How do I use SOCKS5 in Python?
Install the SOCKS extra and use the socks5h:// scheme. The h makes the proxy resolve hostnames, so DNS lookups also exit in the target country. Plain socks5:// resolves DNS on your machine.
# pip install "requests[socks]"
# socks5h:// = the proxy resolves DNS, so lookups also exit in the target country
proxy = proxy_url("ke", scheme="socks5h")
r = requests.get("https://api.ipify.org", proxies={"http": proxy, "https": proxy}, timeout=30)
print(r.text)How do I retry failed requests on a new IP?
Retry on connection errors and on 429 and 5xx responses, with exponential backoff and a little random delay. With a rotating username, each new connection can exit from a new IP, so a retry is also a fresh IP. For sticky work, start a new session ID when an IP fails.
import random
import time
RETRY_STATUS = {429, 500, 502, 503, 504}
def fetch(url, country="ae", attempts=4):
"""Retry with exponential backoff. Each attempt opens a new connection,
so a rotating username exits from a new IP."""
for attempt in range(attempts):
proxy = proxy_url(country)
try:
r = requests.get(url, proxies={"http": proxy, "https": proxy}, timeout=30)
if r.status_code not in RETRY_STATUS:
return r
except (requests.exceptions.ConnectionError, requests.exceptions.Timeout):
pass # ProxyError is a ConnectionError: retry on a new IP
time.sleep(min(2 ** attempt + random.random(), 30))
raise RuntimeError(f"Giving up on {url} after {attempts} attempts")How do I use httpx, sync and async?
Since httpx 0.26, a client takes a single proxy= argument; the old proxies= was removed in 0.28. A client keeps connections alive, and requests on one kept-alive connection share an exit IP. Open a new client, or use a sticky session on purpose, depending on what you need.
# pip install httpx (0.26 or later: the argument is "proxy", not "proxies")
import asyncio
import httpx
# Sync: one sticky IP in Nairobi for 10 minutes
with httpx.Client(proxy=proxy_url("ke", city="nairobi", session=new_session(), ttl=10), timeout=30) as client:
print(client.get("https://api.ipify.org").text)
# Async: 20 connections at most, rotating IPs in Nigeria
async def main(urls):
limits = httpx.Limits(max_connections=20)
async with httpx.AsyncClient(proxy=proxy_url("ng"), timeout=30, limits=limits) as client:
results = await asyncio.gather(*(client.get(u) for u in urls), return_exceptions=True)
for url, res in zip(urls, results):
print(url, res.status_code if isinstance(res, httpx.Response) else repr(res))
asyncio.run(main(["https://api.ipify.org"] * 5))How do I run many requests with aiohttp?
aiohttp takes the proxy per request, with the credentials inside the URL. It supports HTTP proxies only; for SOCKS5 you need an extra package such as aiohttp-socks. Cap concurrency with a semaphore: start around 10 to 20 parallel requests and raise it while your error rate stays low.
# pip install aiohttp (HTTP proxies only; the credentials can sit in the proxy URL)
import asyncio
import aiohttp
async def fetch(session, url, sem):
async with sem:
async with session.get(url, proxy=proxy_url("eg")) as r:
return r.status, await r.text()
async def main(urls):
sem = asyncio.Semaphore(20) # concurrency cap
timeout = aiohttp.ClientTimeout(total=30)
async with aiohttp.ClientSession(timeout=timeout) as session:
results = await asyncio.gather(*(fetch(session, u, sem) for u in urls), return_exceptions=True)
print(results)
asyncio.run(main(["https://api.ipify.org"] * 5))How do I add the proxy to Scrapy?
Write a small downloader middleware that sets request.meta["proxy"]. Scrapy's built-in HttpProxyMiddleware then turns the credentials into a Proxy-Authorization header. Give your middleware a number below 750 so it runs first. Per-request meta keys let one spider mix countries and sticky sessions.
# myproject/middlewares.py
USERNAME = "USERNAME"
PASSWORD = "PASSWORD"
GATEWAY = "gw.namelessproxy.com:7777"
class NamelessProxyMiddleware:
"""Set the proxy per request from request.meta:
country (default 'ae'), optional city, optional session + ttl."""
def process_request(self, request, spider):
meta = request.meta
user = f"{USERNAME}-country-{meta.get('country', 'ae')}"
if meta.get("city"):
user += f"-city-{meta['city']}"
if meta.get("session"):
user += f"-session-{meta['session']}-ttl-{meta.get('ttl', 10)}"
# Scrapy's HttpProxyMiddleware turns the credentials into Proxy-Authorization
meta["proxy"] = f"http://{user}:{PASSWORD}@{GATEWAY}"# myproject/settings.py
DOWNLOADER_MIDDLEWARES = {
# Below 750 so it runs before Scrapy's built-in HttpProxyMiddleware
"myproject.middlewares.NamelessProxyMiddleware": 350,
}
CONCURRENT_REQUESTS = 16
DOWNLOAD_TIMEOUT = 30
RETRY_TIMES = 3
RETRY_HTTP_CODES = [429, 500, 502, 503, 504, 408]
AUTOTHROTTLE_ENABLED = True
ROBOTSTXT_OBEY = True
# In a spider:
# yield scrapy.Request(url, meta={"country": "sa", "city": "riyadh", "session": "cart01"})Frequently asked questions
Why do I get a 407 or ProxyError in Python?
A 407 means the gateway rejected the credentials. Check the base username and the proxy password in the client area, the order of the targeting parts, and any special characters in the password, which must be URL-encoded. A ProxyError without 407 usually means a wrong port or a firewall. Test the same URL with curl from the quick-start guide.
Why does my IP not change between requests?
Your client is probably reusing a kept-alive connection. A requests.Session, an httpx client or an aiohttp session keeps connections open, and one connection keeps one exit IP. For a new IP per request, call requests.get without a session or open a new client. If you added a session ID, the IP is sticky on purpose.
Should I use requests, httpx or aiohttp?
Use requests for simple scripts and small jobs. Use httpx when you want one library for both sync and async code, or HTTP/2. Use aiohttp for large async crawls where you control concurrency yourself. Use Scrapy when you need a full crawler with scheduling, retries and pipelines. All four work with the same proxy URL.
Can one script use several countries at once?
Yes. Targeting is part of each proxy URL, so build a different URL per request or per client: proxy_url("ae") for the UAE and proxy_url("ng") for Nigeria, for example. Traffic is billed from the same balance whatever the country, and the price per GB does not change by country.
How much traffic does a scraper use?
It depends on the pages: an HTML page is often tens to hundreds of kilobytes, while images and scripts add much more. Traffic is counted in decimal GB (1 GB = 1,000,000,000 bytes), and the client area shows daily usage per subscription and sub-user. Fetch only what you parse and skip images to keep costs down.
Does the Python code work with dedicated mobile ports?
Yes, with the port's own host, port, username and password from the client area instead of the gateway values. A dedicated port's country and carrier are chosen when you rent it, and you can move it later. To change its IP from Python, see the mobile IP rotation guide.
Run your Python code through residential IPs
From $0.53/GB, paid in crypto. No KYC — no ID, no selfie, no documents.