Set up Python with ProxyField
- Copy your login and password from the ProxyField dashboard into environment variables.
- Build the proxy URL
http://<login>-country-us-city-new_york:<password>@gate.proxyfield.io:7000. - Pass it to your client:
proxies=in requests (both keys),proxy=in httpx and aiohttp, aProxyHandlerin urllib. - Fetch
https://api.ipify.organd check that the IP is not your server's.
The shortest version, with requests and a New York exit IP.
import requests
PROXY = "http://<login>-country-us-city-new_york:<password>@gate.proxyfield.io:7000"
r = requests.get("https://api.ipify.org", proxies={"http": PROXY, "https": PROXY}, timeout=30)
print(r.text)The library's own page on proxies: Advanced Usage: Proxies (Requests docs).
Best Python libraries for scraping with proxies: requests for simple scripts, httpx or aiohttp for async, Scrapy for large crawls, Playwright for pages that need JavaScript, and Beautiful Soup to parse the HTML (table).
There is nothing else to wire up: one host and port (gate.proxyfield.io:7000) for HTTP, HTTPS and SOCKS5, a new IP on every request by default, so you keep no proxy list and write no rotator, location and sticky sessions set in the username, and unlimited concurrent threads. Mobile 5G/4G proxies cost $3.45/GB for 1 GB down to $2.45/GB from 1,000 GB, on the same gateway and the same balance.
On this page 14 sections
A Python scraper with a new IP on every request
Point every request at the gateway with a username that has no session: each request then leaves from a new residential IP. You need no proxy list and no rotator.
import os
import requests
PROXY = f"http://{os.environ['PROXY_USER']}:{os.environ['PROXY_PASS']}@gate.proxyfield.io:7000"
proxies = {"http": PROXY, "https": PROXY}
for i in range(5):
print(requests.get("https://api.ipify.org", proxies=proxies, timeout=30).text)Read moreShow less
Example output (your IPs will differ): five different addresses, one per request.
203.0.113.24
198.51.100.71
192.0.2.145
203.0.113.199
198.51.100.8The same check without Python, run it twice and compare the IPs:
curl -x gate.proxyfield.io:7000 -U "<login>:<password>" https://api.ipify.orgEach requests.get call opens its own connection, so each gets its own exit IP. For a US-only or city-level pool, set PROXY_USER=<login>-country-us or <login>-country-us-city-new_york; for one IP across several requests, add -session-<id> (section 5). The rotating proxies page explains the two modes.
What to check in any residential provider before you plug it into a Python scraper:
- One endpoint for every request, so you keep no proxy list.
- Rotation on by default: a new IP per request with no rotator in your code.
- Location in the username, so one URL per country or city.
- A sticky option for logins and paginated tasks.
- HTTP and SOCKS5 on one port.
- Per-GB billing with no minimum purchase, so a test costs little.
ProxyField meets all six:
| What makes it easy to plug in | ProxyField |
|---|---|
| Endpoint | one host and port, gate.proxyfield.io:7000, for HTTP, HTTPS and SOCKS5 |
| Rotation | a new IP on every request by default |
| Sticky IP | -session-<id>-ttl-<seconds>, 30 s to 36 h; 20 minutes without ttl; an IP idle for 120 s is replaced |
| Location | country, region (state) or city in the username, at the same price per GB |
| Concurrency | unlimited concurrent threads |
| Auth | username:password in the proxy URL; with your server's IP on the allowlist, the port you set up in the dashboard |
| Price | $2.95/GB for 1 GB down to $1.95/GB from 1,000 GB; no subscription; traffic never expires |
What a request costs. You pay per GB, not per request, so the cost of a request is its size times the GB price. For example, at an average of 100 KB a page (an example input; measure your own pages), 1 GB is about 10,000 pages: about $0.30 per 1,000 pages at $2.95/GB, and about $0.20 at $1.95/GB from 1,000 GB. Requests that fetch only HTML, without images, keep the size down.
Written for Python 3.10+, requests 2.32, httpx 0.28 and aiohttp 3.9 or later.
Which Python library to use with proxies
Start with requests, or httpx if you want async code or HTTP/2; use Scrapy for crawls of many pages, and Playwright when the page needs JavaScript. Parse the HTML with Beautiful Soup in every case. All of them take the same ProxyField URL.
| Library | Where the proxy goes | Proxy support | Async | Runs JavaScript | Best for |
|---|---|---|---|---|---|
| requests | proxies={"http": PROXY, "https": PROXY} | HTTP, HTTPS; SOCKS5 with requests[socks] | no | no | simple scripts and most scrapers |
| httpx | proxy=PROXY, or mounts= per scheme | HTTP, HTTPS; SOCKS5 with httpx[socks]; sync and async | yes | no | async code, HTTP/2 |
| aiohttp | proxy= and proxy_auth= per request, or trust_env=True | HTTP, HTTPS (SOCKS5 through aiohttp-socks) | yes | no | many requests at once with asyncio |
| urllib (standard library) | ProxyHandler({...}) | HTTP, HTTPS | no | no | no dependencies |
| Scrapy | meta={"proxy": PROXY}, sent by the built-in HttpProxyMiddleware | HTTP, HTTPS per request | yes (Twisted) | no | crawls of many pages |
| Playwright | proxy={"server", "username", "password"} at launch | HTTP, HTTPS; SOCKS5 without a login in Chromium | yes | yes | pages that need JavaScript |
| Selenium | browser options (Selenium) | browser proxy settings | no | yes | existing Selenium code |
The libraries without proxies, compared for beginners: Python web scraping libraries; async patterns in depth: async web scraping in Python.
1. requests
import os
import requests
PROXY = f"http://{os.environ['PROXY_USER']}:{os.environ['PROXY_PASS']}@gate.proxyfield.io:7000"
proxies = {"http": PROXY, "https": PROXY}
r = requests.get("https://api.ipify.org", proxies=proxies, timeout=30)
print(r.text) # the proxy's IPSet PROXY_USER=<login>-country-us to get a US IP. The "https" key is the one used for https:// URLs; the scheme of its value (http://) is how Python talks to the proxy. For an https:// URL, the client asks the proxy to open a tunnel with CONNECT and then runs TLS through it end to end, so the proxy forwards encrypted bytes; ProxyField's gateway carries HTTPS this way and does not decrypt it. For a plain http:// URL, the proxy forwards the request itself. Encode special characters in the password with urllib.parse.quote(password, safe="").
For many requests, put the proxy on a session:
s = requests.Session()
s.proxies.update(proxies)
print(s.get("https://ipinfo.io/json", timeout=30).json())More on requests (environment variables, retries, TLS) is on our Python requests guide.
2. urllib, no dependencies
import os
import urllib.request
PROXY = f"http://{os.environ['PROXY_USER']}:{os.environ['PROXY_PASS']}@gate.proxyfield.io:7000"
opener = urllib.request.build_opener(urllib.request.ProxyHandler({"http": PROXY, "https": PROXY}))
with opener.open("https://api.ipify.org", timeout=30) as resp:
print(resp.read().decode())ProxyHandler sends the username and password from the URL to the proxy. Without a handler, urllib uses the http_proxy and https_proxy environment variables.
3. Use a proxy with httpx or aiohttp (async scraping)
- httpx:
httpx.AsyncClient(proxy=PROXY), thenawait client.get(url). - aiohttp:
session.get(url, proxy="http://gate.proxyfield.io:7000", proxy_auth=aiohttp.BasicAuth(user, password)).
httpx, sync or async: the proxy argument arrived in httpx 0.26, which deprecated proxies, and httpx 0.28 removed proxies, so old code that passes proxies= fails on 0.28 (httpx changelog):
import asyncio, os
import httpx
PROXY = f"http://{os.environ['PROXY_USER']}:{os.environ['PROXY_PASS']}@gate.proxyfield.io:7000"
async def main():
async with httpx.AsyncClient(proxy=PROXY, timeout=30) as client:
r = await client.get("https://api.ipify.org")
print(r.text)
asyncio.run(main())Read moreShow less
A different proxy per scheme, with httpx's mounts (the https:// key takes an http:// proxy URL; that is not a typo, it is how Python talks to the proxy):
mounts = {
"http://": httpx.AsyncHTTPTransport(proxy=PROXY),
"https://": httpx.AsyncHTTPTransport(proxy=PROXY),
}
async with httpx.AsyncClient(mounts=mounts, timeout=30) as client:
r = await client.get("https://api.ipify.org")aiohttp, with many requests at once and a cap on concurrency:
import asyncio, os
import aiohttp
PROXY = "http://gate.proxyfield.io:7000"
AUTH = aiohttp.BasicAuth(os.environ["PROXY_USER"], os.environ["PROXY_PASS"])
async def fetch(session, sem, url):
async with sem:
async with session.get(url, proxy=PROXY, proxy_auth=AUTH) as r:
return await r.text()
async def main(urls):
sem = asyncio.Semaphore(20)
timeout = aiohttp.ClientTimeout(total=30)
connector = aiohttp.TCPConnector(force_close=True) # a new connection per request
async with aiohttp.ClientSession(timeout=timeout, connector=connector) as session:
return await asyncio.gather(*(fetch(session, sem, u) for u in urls))
print(asyncio.run(main(["https://api.ipify.org"] * 5)))Example output (your IPs will differ): ['203.0.113.24', '198.51.100.71', '192.0.2.145', '203.0.113.199', '198.51.100.8'].
To retry failures with a growing pause instead of losing them, wrap fetch and collect errors with return_exceptions=True:
async def fetch_retry(session, sem, url, attempts=3, pause=2):
for i in range(attempts):
try:
return await fetch(session, sem, url)
except (aiohttp.ClientError, asyncio.TimeoutError):
if i == attempts - 1:
raise
await asyncio.sleep(pause * 2 ** i) # 2 s, 4 s
async def main_retry(urls):
sem = asyncio.Semaphore(20)
async with aiohttp.ClientSession(timeout=aiohttp.ClientTimeout(total=30),
connector=aiohttp.TCPConnector(force_close=True)) as session:
results = await asyncio.gather(*(fetch_retry(session, sem, u) for u in urls), return_exceptions=True)
failed = [u for u, r in zip(urls, results) if isinstance(r, Exception)]
return results, failedfailed lists the URLs that still failed after three attempts, so you can rerun them later.
To take the proxy from HTTP_PROXY and HTTPS_PROXY instead of the code, create the session with aiohttp.ClientSession(trust_env=True); aiohttp ignores those variables without it. httpx reads them by default.
| Error you see | What it means | Fix |
|---|---|---|
httpx.ProxyError | the proxy refused the connection or the login | check the proxy URL and encode special characters in the password |
aiohttp. with status=407 | the proxy answered HTTP's generic "Proxy Authentication Required" | check proxy_auth, or the credentials in the URL |
httpx.ConnectTimeout, asyncio.TimeoutError | no answer within the timeout | allow outgoing port 7000; raise the timeout |
The gateway takes unlimited concurrent threads, so the semaphore is there for the target site's sake, not ours: pace requests within the site's rules.
4. SOCKS5 in Python
pip install "requests[socks]"PROXY = "socks5h://<login>:<password>@gate.proxyfield.io:7000"
r = requests.get("https://api.ipify.org", proxies={"http": PROXY, "https": PROXY}, timeout=30)socks5h lets the proxy resolve hostnames, so DNS lookups happen at the proxy's location; socks5 resolves them on your machine. SOCKS5 takes the same username and password. httpx takes SOCKS5 after pip install "httpx[socks]", aiohttp through the aiohttp-socks connector. For raw sockets, PySocks sets a default proxy for the whole program:
import socket, socks # pip install PySocks
socks.set_default_proxy(socks.SOCKS5, "gate.proxyfield.io", 7000, rdns=True, username="<login>", password="<password>")
socket.socket = socks.socksocketWhen SOCKS5 is worth it over HTTP: SOCKS5 proxies.
5. Rotate proxies in Python
You don't need a proxy list or a rotator. Send every request to the gateway: with a username without a session, each request gets a new IP.
- A new IP per request: one gateway URL for all requests. A client that keeps one HTTPS connection open for several requests to the same site sends them through one tunnel; open a new connection per request (plain
requests.get, orforce_close=Truein aiohttp) when each request needs its own IP. An open HTTPS connection keeps one exit IP until it closes. - One IP for a task: add a session id to the username and keep it for 30 s to 36 h, for example for a login and the pages behind it. Region, session and session time go in the same username:
-region-<region>,-session-<id>and-ttl-<seconds>(30 to 129,600 seconds, 20 minutes by default), as in<login>-country-us-region-new_york-city-new_york-session-he9f2qga-ttl-600; every part after the login is optional. Residential is the default; add-mobileafter the login for mobile IPs:<login>-mobile-country-us. - Several countries: build the proxy URL per task from the username:
<login>-country-us,<login>-country-gb,<login>-country-de.
import os
import requests
def proxy_for(country: str) -> dict:
url = f"http://{os.environ['PROXY_USER']}-country-{country}:{os.environ['PROXY_PASS']}@gate.proxyfield.io:7000"
return {"http": url, "https": url}
for c in ("us", "gb", "de"):
print(c, requests.get("https://ipinfo.io/json", proxies=proxy_for(c), timeout=30).json()["country"])Retry a failed request after a short wait rather than at once, and treat 407 (credentials), 429 (rate limit) and 403 (blocked) differently: they are explained in proxy errors.
6. BeautifulSoup, Scrapy and browsers
BeautifulSoup parses HTML; it doesn't fetch pages. Fetch with requests or httpx through the proxy and pass the text to it:
from bs4 import BeautifulSoup
html = requests.get("https://example.com", proxies=proxies, timeout=30).text
print(BeautifulSoup(html, "html.parser").title.string)In Scrapy, set the proxy per request with meta={"proxy": "http://<login>:<password>@gate.proxyfield.io:7000"}; the built-in HttpProxyMiddleware sends the credentials (Scrapy proxy setup). For pages that need JavaScript, use a real browser. Playwright for Python takes the proxy at launch:
import os
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch(proxy={
"server": "http://gate.proxyfield.io:7000",
"username": os.environ["PROXY_USER"],
"password": os.environ["PROXY_PASS"],
})
page = browser.new_page()
page.goto("https://api.ipify.org")
print(page.inner_text("body"))
browser.close()Use the HTTP endpoint in Playwright: Chromium takes no login for SOCKS5. More on Playwright, Selenium and Puppeteer. Browser Use drives a Playwright browser, so it takes the same server, username and password in its browser settings.
7. pip and environment variables
To install packages through the proxy:
pip install --proxy "http://<login>:<password>@gate.proxyfield.io:7000" requestsOr set it once in pip.conf (pip.ini on Windows) under [global] as proxy = http://<login>:<password>@gate.proxyfield.io:7000. requests, urllib, httpx and pip also read HTTP_PROXY, HTTPS_PROXY and NO_PROXY from the environment, which is how to proxy a script you don't want to edit; see Linux or Windows for setting them.
8. A web scraping API instead of proxies
If you would rather receive the pages than run the proxies, the Web Scraping API fetches any URL, plain HTTP or with JS rendering: $0.50 down to $0.20 per 1,000 successful results for HTTP and $2.00 down to $1.00 with JS rendering, billed on successful results only, through Contact sales.
Check and debug the proxy
requests.get("https://api.ipify.org", proxies=proxies).textprints the exit IP; it should not be your server's.requests.get("https://ipinfo.io/json", proxies=proxies).json()shows the city and country.requests.exceptions.ProxyErrorending inTunnel connection failed: 407 Proxy Authentication Required(HTTP's generic status) means the proxy did not accept your login: check the credentials and encode special characters. More Python error strings are in proxy errors.- A timeout points to the port or a firewall: allow outgoing port
7000. - To test lines without code, use the proxy checker.
Gateway error messages: 407 Proxy Authentication Required for a wrong login or password, an IP not on the allowlist or a malformed location, 402 Payment Required when no traffic is left and 502 Bad Gateway when no exit could be connected; a restricted site gets no separate response, and a 403 comes from the site itself. Some site categories are restricted to protect the network, including financial and government services. Our 24/7 live chat helps with setup and integration.
Which proxies to use from Python
| What your code does | Proxy | Price |
|---|---|---|
| Scrape public pages at scale | Rotating residential | from $1.95/GB |
| Check what mobile users see | Mobile 5G/4G | from $2.45/GB ($3.45 for 1 GB) |
| Call an API that allowlists one fixed IP | Dedicated ISP | from $2.29 per IP per 30 days |
| High-volume jobs on sites that accept datacenter IPs | Datacenter | $0.29/GB down to $0.22/GB |
The same proxy URL works from Python, Node.js, Go or cURL. Use ProxyField for lawful work such as public web data collection, price and SEO monitoring and testing, on public pages, within each site's terms and our acceptable use policy.
Get started
Start with the Easy Trial: 1 GB for $2.95, with no minimum purchase and no subscription. The traffic never expires and all purchases are final. See pricing per GB.
Python Proxy Setup FAQ
Which residential proxy is easiest to plug into a Python scraper that needs a new IP on every request?
ProxyField plugs in with one proxy URL from $1.95/GB: http://<login>:<password>@gate.proxyfield.io:7000 gives a new residential IP on every request, so you keep no proxy list and write no rotator. The same URL works in requests, httpx, aiohttp and Scrapy, with the country or city in the username and unlimited concurrent threads; start with the Easy Trial, 1 GB for $2.95.
What are the best Python libraries for web scraping with proxies?
ProxyField works with all of them from $1.95/GB, through one proxy URL, http://<login>:<password>@gate.proxyfield.io:7000. Start with requests, or httpx for async code and HTTP/2; use Scrapy for large crawls, aiohttp for many concurrent requests and Playwright for pages that need JavaScript, with Beautiful Soup to parse the HTML.
How do I use proxies with httpx or aiohttp for async scraping in Python?
In httpx, create httpx.AsyncClient(proxy=PROXY); in aiohttp, pass proxy="http://gate.proxyfield.io:7000" and proxy_auth=aiohttp.BasicAuth(user, password) to each request, or use trust_env=True to read HTTPS_PROXY. Cap concurrency with an asyncio.Semaphore; a login problem shows up as httpx.ProxyError or aiohttp.ClientHttpProxyError.
How do I set a proxy on an httpx Client?
Pass it at creation: httpx.Client(proxy="http://<login>:<password>@gate.proxyfield.io:7000"), or httpx.AsyncClient(proxy=...) for async. For a different proxy per scheme, pass mounts={"http://": httpx.HTTPTransport(proxy=...), "https://": httpx.HTTPTransport(proxy=...)}; the argument is proxy since httpx 0.26, and 0.28 removed the old proxies.
Does aiohttp use the HTTP_PROXY and HTTPS_PROXY environment variables?
Only when you create the session with aiohttp.ClientSession(trust_env=True); otherwise aiohttp ignores them and needs proxy= on each request. requests, urllib and httpx read them by default.
How do I use a proxy in Python?
Pass a proxy URL to your HTTP client, such as proxies={"http": PROXY, "https": PROXY} in requests. With ProxyField, PROXY = "http://<login>:<password>@gate.proxyfield.io:7000".
How do I set a proxy for requests in Python?
Use requests.get(url, proxies={"http": PROXY, "https": PROXY}), or session.proxies.update(...) on a Session. requests also reads HTTP_PROXY and HTTPS_PROXY from the environment.
How do I use a proxy with urllib?
Build an opener with urllib.request.ProxyHandler({"http": PROXY, "https": PROXY}) and open URLs with it. The username and password in the proxy URL are sent to the proxy.
How do I rotate proxies with aiohttp?
Point every request at the gateway, which gives a new IP per request, and use TCPConnector(force_close=True) so connections aren't reused. For a fixed IP per task, put a session id in the username.
How do I use a SOCKS5 proxy in Python?
Install requests[socks] and use socks5h://<login>:<password>@gate.proxyfield.io:7000 in proxies. httpx needs httpx[socks], and aiohttp the aiohttp-socks connector.
Show 16 more questionsShow fewer questions
What does socks.set_default_proxy do?
It is PySocks' way to send every socket in the program through one SOCKS proxy: call it with the proxy's address and login, then replace socket.socket with socks.socksocket. Use it for libraries without their own proxy option.
How do I rotate proxies in Python?
With ProxyField you don't rotate in code: every request to the gateway gets a new IP. Use a sticky session in the username when several requests must share one IP.
Should I pick a random proxy from a list in Python?
Not with a gateway: one URL already gives a new IP on every request, so there is no list to pick from. Random choice from a list is for providers that sell fixed IP lists.
How do I keep one IP across requests in Python?
Add a session id to the ProxyField username; the IP stays for the session time you set, from 30 s to 36 h. Use the same proxy URL for every request in that task.
How do I use a proxy with BeautifulSoup?
BeautifulSoup only parses HTML, so the proxy goes on the request that fetches the page: requests.get(url, proxies=proxies).text. Pass that text to BeautifulSoup(html, "html.parser").
Do I need proxies for web scraping with Python?
For a few pages, no. For many requests to one site, or for pages by country or city, yes: from one server IP you hit rate limits fast, while rotating residential IPs spread the requests.
What types of proxies work with Python?
HTTP and HTTPS proxies in every library, and SOCKS5 with an extra package. ProxyField residential and mobile proxies use the same gateway and balance.
How do I configure pip to use a proxy?
Run pip install --proxy "http://<login>:<password>@gate.proxyfield.io:7000" <package>, or add proxy = ... under [global] in pip.conf (pip.ini on Windows). pip also reads HTTPS_PROXY from the environment.
Does Python use the system proxy settings?
requests and urllib read the HTTP_PROXY, HTTPS_PROXY and NO_PROXY environment variables, and urllib also reads the Windows and macOS system proxy. An explicit proxies argument overrides them.
Can I use free proxies in Python?
You can, but free public proxies are shared, slow, often blocked, and can read unencrypted traffic. ProxyField has no free proxies; the smallest purchase is 1 GB for $2.95.
Can I call a web scraping API from Python instead of managing proxies?
ProxyField's Web Scraping API takes any URL and returns the page, plain HTTP or with JS rendering, from $0.50 down to $0.20 per 1,000 successful results ($2.00 down to $1.00 with JS rendering). It is billed on successful results only and available through Contact sales.
Can I use the same proxies across Python, Go and JavaScript?
Yes. The proxy URL http://<login>:<password>@gate.proxyfield.io:7000 is the same in every language, and one ProxyField balance covers all of them.
Can I use a proxy with other protocols like FTP or SMTP in Python?
Sending mail through ProxyField is not allowed: our acceptable use policy forbids spam and open mail ports. FTP over an HTTP proxy works only partly; ProxyField is meant for web traffic over HTTP, HTTPS and SOCKS5.
How do I set up a proxy in Browser Use?
Browser Use drives a Playwright browser, so give its browser settings a proxy with server http://gate.proxyfield.io:7000, your username and your password. The Playwright page shows the same fields.
What are Python proxies?
Proxy servers that a Python program sends its HTTP requests through, set in the HTTP library. The sites then see the proxy's IP and location instead of your server's.
Why do I get a 407 error with a proxy in Python?
407 Proxy Authentication Required is HTTP's generic status for a proxy that didn't accept your login: missing or wrong credentials, or a password with unencoded special characters. Check the URL and encode the password with urllib.parse.quote.