Skip to content

Guide

Python requests proxy

Requests takes a proxies dictionary and that is genuinely the whole of it, but three things trip people up. The same URL has to be given for both http and https, authentication goes in the URL rather than in a header, and SOCKS5 needs an extra package that requests does not install by default. Here is a setup that works.

The working snippet

One proxy URL, used for both schemes. The https key does not mean the connection to the proxy is encrypted, it means requests sent to https destinations go through this proxy, which is the part people misread.

python
import requests

PROXY = "http://USERNAME:[email protected]:80"

proxies = {"http": PROXY, "https": PROXY}

r = requests.get("https://api.ipify.org?format=json", proxies=proxies, timeout=30)
print(r.json())

Hold one address across several requests

A Session reuses the connection and keeps the same exit address for as long as the pool allows, which is what you want for anything that spans more than one page, such as a cart or a signed in flow. Residential sessions here hold for up to six hours.

python
import requests

PROXY = "http://USERNAME:[email protected]:80"

with requests.Session() as s:
    s.proxies.update({"http": PROXY, "https": PROXY})

    first = s.get("https://example.com/login")
    second = s.get("https://example.com/account")

SOCKS5, and the package requests does not ship

Requests cannot speak SOCKS5 on its own. Install the extra, then use socks5h rather than socks5. The h is what makes the destination hostname resolve at the proxy instead of on your machine, and without it your own DNS leaks the target and can resolve it to the wrong regional address.

shell
pip install "requests[socks]"

Then point it at the SOCKS port

Every pool publishes an HTTP port and a SOCKS port, and they are not always the same number. Residential runs both on 80, mobile runs 8080 and 1080, datacenter runs 777 and 666, ISP and IPv6 run 30 and 31. Your dashboard shows the pair for whatever you bought.

python
PROXY = "socks5h://USERNAME:[email protected]:80"

proxies = {"http": PROXY, "https": PROXY}

What to buy

Residential per GB if the target inspects who is asking, datacenter per GB if it does not. Start with datacenter, because it is cheaper and a great many targets never notice, and move up only for the sites that actually block you.

Common questions

Why does the https key use an http URL?

Because that key selects which proxy handles requests to https destinations, not which scheme is used to reach the proxy. Sending https traffic through an http proxy is normal and is how CONNECT tunnelling works. Putting https in the value is a common fix attempt that breaks a setup which was already correct.

My proxy works in curl but not in requests.

Almost always an environment variable. Requests reads HTTP_PROXY, HTTPS_PROXY and NO_PROXY from the environment, and a value there can override or conflict with what you passed in. Check them first, or pass trust_env as false on the Session to make requests ignore them entirely.

How do I check it is actually working?

Request an address echo service through the proxy and compare it to your own address without one. If both answers match, the traffic is not going through the proxy, whatever the code looks like. Do that once before building anything on top.

Try it against your own target

Metered bandwidth is billed per gigabyte and does not expire, so testing a small amount against the site you actually care about costs very little.

More guides