New Residential Premium, our top-tier pool for the toughest sites
PY

Scraping & code · Setup guide

How to use a proxy with Python requests

requests takes a proxy URL for each scheme in a proxies dict. Paste a line from your ZenProxy generator and every request goes out through it, with the username and password sent for you.

Broken on our side? Fixed in 48h or refunded.

Quick setup

  1. 1Copy a line in protocol://username:password@hostname:port format.
  2. 2Pass proxies={"http": url, "https": url} to requests.
  3. 3Open a new connection per request for a new IP, or use a sticky line to keep one.
  4. 4Install requests[socks] and use socks5h:// for SOCKS5.

Your proxy details

After you buy a plan, open My proxies. Choose the Proxy Type (Rotating or Sticky), the Protocol (HTTP or SOCKS5) and a Format, then copy a line. The generator offers three formats:

HOST:PORT:USERNAME:PASSWORD

Paste into apps and anti-detect browsers that split the fields or auto-fill them.

USERNAME:PASSWORD@HOST:PORT

Tools that want credentials before the address.

http://USERNAME:PASSWORD@HOST:PORT

Code and command-line tools. This is the proxy URL used in the examples below.

In the examples on this page, replace USERNAME, PASSWORD, HOST and PORT with the values from your line. SOCKS5_PORT is the port the generator shows when you pick SOCKS5.

Residential lines are either rotating (a new IP on new connections) or sticky (one IP for the time you choose). Datacenter and ISP plans give you a list of dedicated IPs, one per line as IP:PORT:USERNAME:PASSWORD, and each line is one fixed IP.

To test a line, open https://ipinfo.io/json through it: it shows the exit IP and country. For HTTP lines you can also use the free proxy checker.

Basic authenticated proxy

Put the username and password in the proxy URL. requests turns them into the Proxy-Authorization header, including for HTTPS sites, which it reaches through a CONNECT tunnel.

Python
import requests

proxy = "http://USERNAME:PASSWORD@HOST:PORT"
proxies = {"http": proxy, "https": proxy}

r = requests.get("https://ipinfo.io/json", proxies=proxies, timeout=30)
print(r.json())  # the exit IP and its country

Both keys point to the same http:// URL. The key is the scheme of the site you visit; the value is how to reach the proxy. Keep http:// in the value even for HTTPS sites. Your traffic is still encrypted end to end inside the tunnel, and writing https:// there makes requests try TLS to the proxy itself, which fails with an SSL error.

Use a Session for many requests

A Session reuses connections, which is faster when you send many requests to the same site.

Python
import requests

proxy = "http://USERNAME:PASSWORD@HOST:PORT"

with requests.Session() as s:
    s.proxies.update({"http": proxy, "https": proxy})
    r = s.get("https://ipinfo.io/json", timeout=30)
    print(r.json()["ip"])

requests also reads the HTTP_PROXY and HTTPS_PROXY environment variables. A proxies= argument passed to a single call always takes priority over them, so pass it per call when your machine has those variables set.

Rotating and sticky IPs

Rotation happens per connection. A rotating line gets a new IP when your client opens a new connection; requests sent through the same open HTTPS tunnel leave from the same IP. requests.get() without a Session opens a new connection on every call, so a rotating line gives you a new IP each time. Inside one Session, requests to the same site can share an IP while the connection stays open.

To make sticky lines, open the generator, set Proxy Type to Sticky, choose a Sticky Duration if your plan offers one, set how many lines you want in Sticky Amount, then copy or download them. Each line keeps its IP for the chosen time. The session part of a sticky username differs by plan, so always generate sticky lines instead of editing usernames by hand.

Rotating line: a new IP per call
import requests

proxy = "http://USERNAME:PASSWORD@HOST:PORT"  # rotating line
proxies = {"http": proxy, "https": proxy}

for _ in range(3):
    print(requests.get("https://ipinfo.io/json", proxies=proxies, timeout=30).json()["ip"])
Sticky lines: one IP per task
import random
import requests

# sticky.txt: lines downloaded from the generator
# (Proxy Type: Sticky, Format: protocol://username:password@hostname:port)
with open("sticky.txt") as f:
    lines = [line.strip() for line in f if line.strip()]

proxy = random.choice(lines)
proxies = {"http": proxy, "https": proxy}

# Both calls leave from the same IP until the sticky duration ends.
print(requests.get("https://ipinfo.io/json", proxies=proxies, timeout=30).json()["ip"])
print(requests.get("https://ipinfo.io/json", proxies=proxies, timeout=30).json()["ip"])
Any generator format to a proxy URL
from urllib.parse import quote


def to_proxy_url(line: str, scheme: str = "http") -> str:
    """Turns any generator format into a proxy URL."""
    line = line.strip()
    if "://" in line:  # protocol://username:password@hostname:port
        return line
    if "@" in line:  # username:password@hostname:port
        return f"{scheme}://{line}"
    host, port, user, password = line.split(":", 3)  # hostname:port:username:password
    return f"{scheme}://{quote(user, safe='')}:{quote(password, safe='')}@{host}:{port}"

Datacenter and ISP plans give you a list of dedicated IPs (IP:PORT:USERNAME:PASSWORD). Each line is one fixed IP; to rotate, pick a different line per request with the helper above.

Target a country

On residential plans, add -country- and a two-letter country code to the end of the username, for example USERNAME-country-us or USERNAME-country-gb. To combine a country with a state, a city or a sticky session, build the line in the generator, which shows only the options your plan supports. Datacenter and ISP IPs have a fixed location that you choose when you buy them.

Python
proxy = "http://USERNAME-country-us:PASSWORD@HOST:PORT"
proxies = {"http": proxy, "https": proxy}

SOCKS5

SOCKS support in requests needs an extra package. Pick SOCKS5 as the protocol in the generator to get the SOCKS5 port and a socks5:// line.

Install
pip install "requests[socks]"
Python
import requests

proxy = "socks5h://USERNAME:PASSWORD@HOST:SOCKS5_PORT"
proxies = {"http": proxy, "https": proxy}

print(requests.get("https://ipinfo.io/json", proxies=proxies, timeout=30).json())

Use socks5h://, not socks5://. With socks5h, the proxy resolves the site’s hostname, so DNS lookups don’t leak from your machine and the site sees a lookup from the exit country. With socks5, requests resolves the name locally first.

Other Python libraries

Async code: HTTPX and aiohttp. Crawling at scale: Scrapy. Real browsers: Playwright and Selenium. RAG pipelines: LangChain.

Tips

  • Always pass timeout=. Without it, requests can wait forever on a stalled connection.
  • Retry failed requests with a fresh call (a new connection), not inside the same Session, so a rotating line gives you a new IP.
  • If your password has special characters, URL-encode it with urllib.parse.quote(password, safe="").

Troubleshooting

  • ProxyError … Tunnel connection failed: 407 Proxy Authentication Required

    The username or password is wrong or wasn’t sent. Copy a fresh line from the generator and URL-encode special characters.More on this error →

  • SSLError … WRONG_VERSION_NUMBER

    The proxy URL starts with https://. Change it to http://.More on this error →

  • InvalidSchema: Missing dependencies for SOCKS support

    Run pip install "requests[socks]".

  • The IP doesn’t change on a rotating line

    Your client is reusing an open connection. Requests that share a tunnel share its IP. Open a new connection per request, or use one sticky line per task.More on this error →

  • Timeouts

    Set an explicit timeout of 30–60 seconds, retry on a new connection, and lower concurrency.More on this error →

Seeing another error? Read proxy errors and how to fix them, or contact support.

Questions

Does Python requests support proxy authentication?

Yes. Put the credentials in the proxy URL, as in http://USERNAME:PASSWORD@HOST:PORT. requests sends them to the proxy for both HTTP and HTTPS sites.

How do I get a new IP for every request?

Use a rotating line and open a new connection per request, for example by calling requests.get() without a Session. Requests that reuse one open connection share its IP.

Should I use socks5 or socks5h?

Use socks5h://. It lets the proxy resolve hostnames, so DNS doesn’t leak from your machine and location-aware sites see a lookup from the exit country.

Can I set the proxy with environment variables?

Yes. requests reads HTTP_PROXY and HTTPS_PROXY. A proxies= argument on a call overrides them.

Try it with Python for $0.49

Get 1 GB of Residential Lite, then copy your rotating or sticky lines from the generator and paste them into the steps above.

Broken on our side? Fixed in 48h or refunded.

Related guides

All integrations →