Python requests through an authenticated proxy, step by step

Updated:

To use a proxy in Python requests, pass a proxies dict whose 'http' and 'https' keys both point to http://user:pass@ip:port. Put that dict on a requests.Session() and the same connection to the proxy is reused for every call, which is faster than opening a new one per request. Below: the dict, the session, the errors you are likely to hit, and a one-line check of the ProxyV4 exit IP.

Python Requests · HTTP Proxy Format
proxies = {'http': 'http://user:pass@ip:port', 'https': 'http://user:pass@ip:port'}

The proxies dict, explained

SettingValueReason
'http' key'http://user:pass@ip:port'Used for plain http:// URLs
'https' key'http://user:pass@ip:port'Still an http:// proxy URL: urllib3 asks the proxy for a CONNECT tunnel and runs TLS inside it
timeouttimeout=(5, 15)5 s to connect, 15 s to read, so a dead target cannot freeze a thread
Rotationitertools.cycle(proxy_list)Hands out your static IPs in turn

Why a Session beats bare requests.get()

Each top-level requests.get() call builds a fresh connection pool, so the TCP connection to the proxy and the TLS handshake with the site are repeated every time. A Session keeps those connections alive between calls. For a script that fetches hundreds of pages through one IP, that difference is visible in the total run time.

Set s.proxies.update(proxies) once and every s.get() and s.post() goes through the proxy. One thing to know: if HTTP_PROXY or HTTPS_PROXY are set in the environment, requests may combine them with the session's settings; pass proxies= on the call itself when you need to be certain which one is used.

Errors and how to read them

  • ProxyError with 407 Proxy Authentication Required: the proxy is reachable but the login in your URL does not match the order. See the 407 error page
  • Passwords containing @, : or / break the URL; encode them first with urllib.parse.quote(password, safe='')
  • Switching the proxy URL to https:// usually breaks the connection; keep http:// for both keys unless your proxy port is specifically a TLS port
  • ConnectTimeout points at the IP or port, not the credentials; test reachability with the port checker

Same pattern in httpx and aiohttp

The URL format carries over. In httpx, create httpx.Client(proxy='http://user:pass@ip:port'); in aiohttp, pass proxy= to session.get(url, proxy=...). Larger crawls with scheduling and retries are usually easier in Scrapy.

Step by step

  1. 1

    Build the proxy URL

    Rewrite each ProxyV4 ip:port:user:pass line as http://user:pass@ip:port, or convert the whole list with the proxy format converter.

  2. 2

    Create the dict

    Write proxies = {'http': 'http://user:pass@ip:port', 'https': 'http://user:pass@ip:port'}.

  3. 3

    Attach it to a Session

    Create s = requests.Session() and call s.proxies.update(proxies) so connections are kept alive between requests.

  4. 4

    Print the exit IP

    Run print(s.get('https://proxyv4.com/api/my-ip', timeout=10).json()); the IP in the output should be the proxy's.

Frequently asked questions

Why is the 'https' entry an http:// URL?

The scheme describes how Python talks to the proxy, not to the website. urllib3 connects to the proxy over plain HTTP, sends CONNECT, and then does TLS with the https:// site through that tunnel, so the page traffic is still encrypted.

How do I spread requests over 25 static proxies?

Put the 25 URLs in a list, create pool = itertools.cycle(PROXIES), and for each request take p = next(pool) and pass proxies={'http': p, 'https': p}. Keep a sensible delay per IP so no single address is hammered.

Is traffic from Python scripts metered?

No. ProxyV4 private IPv4 and static ISP plans come with unlimited bandwidth, so long-running scripts do not run into a data cap.

A static IP pool for Python scripts

Private IPv4 in 7 countries plus static ISP in the US and Vietnam. Buy a single IP or a batch; the price per IP falls with quantity.

Check live US prices

Related articles

Proxies by platform
Proxies for web scraping: a fixed pool of IPs with unmetered traffic
Web scraping proxies for Python, Scrapy, Playwright and Selenium: a pool of private IPv4 and static ISP addresses, unlimited bandwidth, flat per-IP pricing.
Proxy setup
Playwright proxy authentication, one static IP per context
Give each Playwright browser context its own authenticated HTTP(S) proxy in Node.js or Python, match timezone and locale to the IP and confirm the exit address.
Proxy setup
Scrapy proxies: meta['proxy'], middleware order and rotation
Use authenticated HTTP(S) proxies in Scrapy: set request.meta['proxy'], order your middleware before HttpProxyMiddleware (750), rotate IPs and pace your crawl.
Free tools
Rewrite a proxy list into the format your tool expects
Convert proxy lists in your browser between ip:port:user:pass, user:pass@ip:port, http:// URLs, SOCKS5 URIs, JSON arrays and FoxyProxy import files, in bulk.
Proxies by platform
Proxies for SEO rank tracking: see the results page a local searcher sees
SEO rank tracking proxies with a private IPv4 in the US, UK, Vietnam, Japan and four more markets, so rankings, local packs and ads match what locals see.
Proxies by platform
Amazon seller proxies that give each account a permanent address
Amazon seller proxies for Seller Central, KDP and Merch: a US static ISP or UK/Japan private IPv4 per account, rented to you alone and kept on renewal.
IPV4 · united states
Build a US IP Pool for Scraping, Rank Tracking and Ad Checks
Buy US private IPv4 proxies: static American datacenter IPs, one customer per IP, unlimited bandwidth. Built for scraping, SERP tracking and US ad checks.
IPV4 · vietnam
Vietnamese IPv4 at Volume: One Fixed IP per Account Without the ISP Price
Vietnam private IPv4 proxies: static Vietnamese datacenter IPs, one customer each, priced for volume. For seeding profiles, secondary Shopee shops and tools.