A requests proxy is two lines of code — the money sits in the IP behind it
Everyone knows the drill: import requests, pass a dictionary with the endpoint, read the response. That part takes a minute. The part that burns a week is page eleven, when the target starts answering with 403, an interstitial captcha, or a polite empty JSON that quietly poisons your dataset. Rewriting headers for two more days rarely fixes that; changing the exit IP usually does.
So this page is about the practical side. What to put in the proxies dictionary, when SOCKS5 is worth the extra install, how to handle rotation on long jobs, and what the invoice looks like when the meter runs on ports instead of gigabytes. Fewer retries, cleaner data, one predictable line in the monthly budget — that is the entire job of a requests proxy.
The proxies dictionary: a working example
The library expects a plain Python dictionary where the keys are schemes and the values are the endpoint. A minimal example looks like this: proxies = {"http": "http://login:password@host:port", "https": "http://login:password@host:port"}, then requests.get(url, proxies=proxies, timeout=30). Both keys point at the same HTTP endpoint on purpose — the https key describes the target scheme, not the proxy scheme. Nothing else in your crawler changes, so a project that already works locally starts exiting from a carrier IP after a single edit.
Authentication comes in two flavors, and having both available saves refactoring later. Login:password travels with the script and works from a laptop, a colleague's machine, or a fresh VPS. IP whitelisting is cleaner on a fixed server where you would rather keep credentials out of the repository. Pick whichever fits the deployment today, switch tomorrow, keep the same code.
One habit pays for itself immediately: verify the exit before launching the full run. Send a single request to an IP-intelligence endpoint, print the response, and look at the type field — it must read mobile, with a fraud score in the low range instead of the 75-plus that hosting ranges collect. Two seconds of checking prevents the classic scenario where a "mobile" package turns out to be a hosting range and the whole night of scraping returns nothing usable.
Pro-tip: keep that verification call as a permanent first step of the job and abort on a bad type. A crawler that refuses to start on a wrong exit is cheaper than a crawler that runs for six hours and writes garbage into your database.
Using a requests socks5 proxy when HTTP-level tunneling is not enough
SOCKS5 support is not bundled by default. Install the extra with pip install "requests[socks]", then write the value as socks5h://login:password@host:port. The trailing h sends DNS resolution to the proxy side, which keeps hostnames off your own resolver — useful when the target correlates lookups with sessions. For automation that also drives an anti-detect browser, SOCKS5 is effectively mandatory, so one protocol covers both halves of the stack instead of forcing two vendors.
A requests socks5 proxy also behaves better with anything that is not plain HTTP: UDP-based checks, WebRTC-adjacent tooling, custom clients wrapped around the same credentials. If a provider offers HTTP only, half of that list stays out of reach. Support for HTTP(S) and SOCKS5 on the same port means the tooling you add next month still connects.
Sticky sessions and rotation: choose per job, not per habit
Long scrapes and account work want opposite things. A login flow, a paginated cart, or a sequential crawl through a catalog needs the same IP for minutes at a time, otherwise the session dies mid-way and every retry costs bandwidth and time. Mass collection of independent pages prefers a new IP every few requests, which spreads the rate limit instead of hitting it head-on. Matching the mode to the job is what moves success rate from "works sometimes" to "finishes overnight".
| Mode | How it fires | Best for |
| Sticky session | IP held for a set interval | Logins, paginated flows, checkout paths |
| Rotation by link | Your script calls a change-IP URL | Batch scraping with full control in code |
| Rotation by timer | Automatic change on interval | Long unattended jobs |
| Device reboot | Full re-connect of the modem | Recovering a stuck or rate-limited exit |
On the Regular plan the device is yours for the whole rental, so all four controls are available — including the reboot that rescues a jammed run without opening a ticket. The Lite plan shares one device between up to five users and rotates automatically every two to five minutes with no manual control. For a background price monitor that tolerates a changing exit, Lite is the cheaper answer; for anything with a session inside it, the dedicated device removes the guesswork.
Pro-tip: call the rotation link from your retry handler, not from a fixed loop. Rotating only after a 429 or a captcha response means you keep the good IP as long as it works and burn a new one only when the old one is actually spent.
Why the carrier IP changes the numbers
Guarded targets sort traffic by the network it came from before anything else happens. Hosting ranges are the easiest thing in the world to flag, home ISP ranges do better, and carrier ranges sit at the top of the trust ladder because thousands of real subscribers share each address. Blocking one of those addresses would cut off a crowd of paying customers, so platforms answer with soft measures instead of hard bans — and your script gets data where the same code on a cheap endpoint got a challenge page.
| Proxy type | ASN the target sees | Typical outcome on guarded targets |
| Datacenter | hosting | Fast, cheap, blocked early |
| Residential (other category) | isp | Often under 80% success rate |
| Mobile (OnlineProxy) | mobile | 95–99% on the same endpoints |
Speed is the honest trade-off: a cellular channel gives roughly 50–300 ms latency and moderate throughput, so bulk video downloads are the wrong use case. For HTML, JSON APIs, and SERP collection that difference disappears next to the cost of failed attempts. Nineteen clean pages out of twenty beat fifty attempts that return challenge screens.
Geo and operator targeting for data that reflects reality
Position tracking, ad verification, and marketplace monitoring all depend on where the request appears to originate. Country level is rarely enough — a mobile SERP from one city and one carrier differs from what a desktop range returns, and that difference is precisely the datum a client is paying you to report. Targeting down to city and operator turns a rough estimate into a number you can put in a report without a disclaimer.
Consistency matters just as much as the address. Language, timezone, and currency in your headers should agree with the geo of the exit, otherwise the mismatch itself becomes the signal. Keep those aligned per profile and the same script can cover a list of markets from one codebase.
Ports, not gigabytes: how the bill behaves
Per-gigabyte pricing punishes exactly the traffic pattern scrapers produce — retries, redirects, and heavy pages all show up on the invoice. OnlineProxy bills per port for a period: one day, seven days, or thirty, with 24 hours as the minimum unit and unlimited traffic on both plans. That means no metering by volume, so an experiment that suddenly pulls ten times more pages costs the same as a quiet one. Budgeting a requests proxy becomes arithmetic instead of forecasting.
Prices depend on country and operator and are shown on the plan page itself. Cashback is credited as promo balance after a paid rental ends, and refunds follow the refund and replacement policy: full within the first hour after access is issued, later minus the time already used, with a replacement proxy offered first when the issue is technical. Support runs around the clock with a target first response of four hours, and a free server proxy is available through the site widget if all you need right now is to confirm that your plumbing works before renting a carrier port.
Mistakes that quietly ruin a run
- No timeout in the request call — one stalled connection freezes a worker for hours.
- Reusing a single port across many accounts on the same platform, which links them together.
- Ignoring fingerprints when browser automation is involved: the network identity is only one layer.
- Firing requests at machine speed with zero delay, which triggers rate limiting no matter how clean the IP is.
- Skipping the exit check, then discovering the collected data came from challenge pages.
None of these are exotic. Each one is a line or two in the script, and fixing them before launch is the difference between a job that finishes and a night wasted. Add the checks once, reuse them in every project.
The short version: keep the code boring, keep the exit trustworthy, and pay for the port rather than the traffic. A requests proxy built that way stops being the fragile part of your pipeline and becomes the part you no longer think about.