Pricing data · 11 countries

Mobile proxies for price monitoring

Retail, travel and marketplace sites localise aggressively: the price, currency, stock status and delivery estimate you are shown all depend on where the request appears to come from. They also rate-limit hard. Together those two facts mean a repricing pipeline fed from one fixed IP drifts quietly wrong — and a wrong price that arrives on schedule looks exactly like a right one.

Start with $2 free creditSee pricingNo subscription · pay per GB

The problem: silent staleness, not loud failures

The failure mode that costs money is not the 403 — you can see a 403. It is the page that returns 200 with a cached, default-region or logged-out price, served because the site decided your IP was not a shopper. Your parser is happy, your dashboard is green, and your repricing engine is now acting on a number that no customer would ever be quoted. Carrier IPs get the shopper treatment because they look like shoppers, which is the entire reason this workload moved to mobile pools.

You will recognise this if

  • A competitor's price that has not moved in weeks, while their site shows it changing daily.
  • Prices in the wrong currency, or with the wrong VAT treatment, for the market you are tracking.
  • "Out of stock" everywhere, because the stock check is geo-scoped and your exit is not in the region.
  • Escalating captcha and interstitial rates the longer a crawl runs.
  • Shipping estimates that never populate, because they depend on a plausible postal geography.

Working code

Every block below runs as written once PROXY_URL holds a real connection string. Copy yours from the dashboard after your first top-up.

Set the connection URL

bash
export PROXY_URL="http://USERNAME-mbl-de-rot-auto10:[email protected]:7000"

# Swap the country token (de -> fr, es, gb ...) to move market.
# Nothing else in your code changes.

Python — a polite, resilient price collector

python
import os, time, random
import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry

PROXY = os.environ["PROXY_URL"]

session = requests.Session()
session.proxies = {"http": PROXY, "https": PROXY}
session.headers["User-Agent"] = (
    "Mozilla/5.0 (Linux; Android 14; Pixel 8) AppleWebKit/537.36 "
    "(KHTML, like Gecko) Chrome/125.0 Mobile Safari/537.36"
)

# Back off on 429/5xx and honour Retry-After rather than hammering.
retry = Retry(
    total=4,
    backoff_factor=1.5,
    status_forcelist=(429, 500, 502, 503, 504),
    respect_retry_after_header=True,
    allowed_methods=frozenset(["GET"]),
)
session.mount("https://", HTTPAdapter(max_retries=retry, pool_maxsize=20))

def fetch_price(url: str) -> str:
    r = session.get(url, timeout=30)
    r.raise_for_status()
    # Guard against the silent-staleness failure: if the page did not come
    # back in the currency you expect, treat it as a miss, not a price.
    if "€" not in r.text:
        raise ValueError(f"unexpected currency for DE exit: {url}")
    return r.text

for url in ["https://shop.example/p/1", "https://shop.example/p/2"]:
    html = fetch_price(url)
    print(len(html), url)
    time.sleep(random.uniform(1.5, 4.0))   # pace yourself

The currency assertion is the important line. It converts the expensive silent failure into a visible one.

Python — session-scoped checks that need a cart

python
# Shipping cost and tax often only appear once an item is in a basket,
# which means the whole flow must run on one IP. Use a sticky session:
#   ...-mbl-de-sid-basket01-rot-sticky:PAK_KEY@...
import os, requests

s = requests.Session()
s.proxies = {"http": os.environ["PROXY_URL"], "https": os.environ["PROXY_URL"]}

s.post("https://shop.example/cart/add", data={"sku": "ABC", "qty": 1}, timeout=30)
quote = s.get("https://shop.example/cart/shipping", timeout=30).json()
print(quote["currency"], quote["total"], quote["eta_days"])

One -sid- per concurrent basket. Reusing a sid across two workers puts them in the same cart.

Which rotation mode to use

Recommended-rot-auto10

Catalogue sweeps are the classic rotation workload: many independent reads, no state to preserve between them, and a per-IP request budget you do not want to exhaust. auto10 gives you a fresh carrier IP roughly every ten minutes, which spreads a long crawl across many exits without you having to orchestrate anything. Pair it with real pacing — a second or two of jitter between requests — because rotation buys you headroom, not permission to run flat out.

When to choose something else

ModeUse it when
stickyAnything that spans requests: adding to a basket to reveal shipping cost, a logged-in trade price, a multi-step checkout quote. Use one -sid- per concurrent worker.
auto30Low-frequency monitoring — a daily or hourly sweep of a few hundred SKUs — where a slower churn is plenty.
hardYou need the device pinned for a long-running session and want the strictest guarantee the pool offers.

Expected bandwidth use

Price monitoring is cheap if you fetch HTML and expensive if you render. The single biggest lever on your bill is whether you drive a browser or not — and for most retail sites, you do not have to.

WorkloadPer unitPer GB
Product page, HTML only (requests/httpx)150–400 KB~2,600–7,000 pages
Category/listing page, HTML only300–700 KB~1,500–3,500 pages
Internal pricing JSON/GraphQL endpoint5–40 KB~26,000–200,000 calls
Full browser render of a JS-heavy PDP2–5 MB~200–520 pages

Before building a browser-based scraper, open the network tab and look for the JSON endpoint the page itself calls for price and stock. Most modern storefronts have one, and hitting it directly is between fifty and two hundred times cheaper per read than rendering the page around it. Figures above are typical ranges from real retail targets — meter your own before sizing a monthly budget.

BandwidthPricePer GBSave
1 GB$7$7—
5 GB$35$7—
10 GB$68$6.803%
25 GB$150$614%
50 GB$283$5.6619%
100 GB$500$529%

Relevant countries

Change country by editing one token in the proxy username — no redeploy, no second account. Pool depth varies by country and by whether you use the mobile (mbl) or residential (peer) pool; live availability is shown on each country page and in your dashboard.

Legitimate use only

ProxyMobile is sold for measurement, quality assurance and research on systems you own or are authorised to test. Buying bandwidth does not grant permission to access a third party's systems. You remain responsible for complying with each target's terms of service, robots directives and rate limits, and with the data-protection law that applies to you.

For this use case

  • Collect prices that are published publicly. Do not authenticate into a trade or wholesale portal you have no account for.
  • Respect robots directives and any documented crawl-rate guidance on your targets.
  • Cache aggressively and re-fetch only what actually changes. Re-crawling a static catalogue nightly is cost you pay and load someone else absorbs.
  • Personal data attached to listings — seller names, reviewer identities — is out of scope for pricing work. Do not collect it incidentally.

Never, on any plan

  • No credential stuffing, account takeover, or any attempt to authenticate as someone else.
  • No circumventing an access control, paywall or security measure you have not been authorised to test.
  • No collection of personal data you have no lawful basis to process.
  • No load that a reasonable operator would experience as a denial of service — throttle, back off on 429s, and honour Retry-After.

Accounts used for fraud, intrusion or bulk abuse are terminated without refund, and we cooperate with valid legal process. Full terms are in our acceptable use policy.

Price monitoring FAQ

Why do I get stale or wrong-region prices from a datacentre proxy?

Because the site geolocates and classifies the IP before rendering. Cloud ranges commonly receive a cached default-region page, a logged-out price, or a soft block that still returns HTTP 200. Your parser cannot tell the difference, which is why the failure shows up as bad data rather than as an error.

Should I use a browser or plain HTTP requests?

Plain requests wherever the data is in the HTML or in a JSON endpoint the page calls — it is roughly ten to two hundred times cheaper per read. Reach for a browser only when the price genuinely requires client-side execution to appear.

How do I track shipping cost, which only appears at checkout?

Use a sticky session so the whole basket flow runs from one IP. Add -sid- with a per-worker identifier and -rot-sticky, then drive the add-to-cart and shipping-quote steps on that session.

How much bandwidth does a catalogue sweep use?

For HTML-only product pages, expect roughly 2,600 to 7,000 pages per gigabyte. If the site exposes a pricing JSON endpoint you can often get tens of thousands of reads from the same gigabyte.

Can I monitor a competitor's prices legally?

Collecting publicly displayed prices is common commercial practice in most jurisdictions, but the specifics depend on your location, the target's terms and how you use the data. We require that you stay within each target's terms and applicable law; we are not able to give you legal advice about your particular programme.

Related guides

Try it against your own targets

Bandwidth estimates on this page are honest ranges, not promises — the only number that matters is what your targets cost you. Your first top-up is credited with an extra $2, which is enough to meter a real run before you size a budget.