Amazon Scraper API vs Proxy: Choose a Product Data Source
Compare seller APIs, licensed Amazon product data and proxy page checks by record, access scope and reuse rights.
Read guideSet DrissionPage’s Chromium proxy before startup, check the reported exit address, and verify the required target content.

Set ChromiumOptions.set_proxy() before creating ChromiumPage, then check an IP echo and the required target marker in the same browser. DrissionPage’s documented set_proxy() accepts a scheme, host, and port without proxy credentials; use an authenticated local bridge when the upstream requires a username and password.
Use Python 3.12 and Google Chrome 154.0.8037.58 or another Chromium build with PerformanceNavigationTiming.responseStatus. The property has limited cross-browser availability; the example fails closed if it returns 0. This exact setup was run with Python 3.12.0 and Chrome 154.0.8037.58 on macOS. Install Python from python.org and Chrome from the official Chrome download page.
Warning: The proxy may see destination metadata, and proxy credentials can leak through logs or an unencrypted hop. This example accepts an unauthenticated proxy endpoint only. Keep the target permitted and read-only; use an HTTPS proxy hop when supported, and remove temporary secret bindings after a run.
Install the tested Python package:
python3.12 -m venv .venv
. .venv/bin/activate
python -m pip install 'DrissionPage==4.1.1.4'
Set PROXY_SERVER, IP_CHECK_URL, TARGET_URL, and EXPECTED_MARKER in the environment. PROXY_SERVER contains only the scheme, host, and port, for example http://proxy.example:8080. Use an HTTPS IP echo endpoint that returns JSON with an origin field.
Save this complete example as drissionpage-check.py. It creates a fresh browser profile, disables connection retries, and checks the response status before inspecting a bounded amount of rendered text.
import ipaddress
import json
import os
from urllib.parse import urlsplit
from DrissionPage import ChromiumOptions, ChromiumPage
PROXY_SERVER = os.environ["PROXY_SERVER"]
IP_CHECK_URL = os.environ["IP_CHECK_URL"]
TARGET_URL = os.environ["TARGET_URL"]
EXPECTED_MARKER = os.environ["EXPECTED_MARKER"].strip()
MAX_TEXT_CHARS = 12_000
proxy_parts = urlsplit(PROXY_SERVER)
try:
proxy_port = proxy_parts.port
except ValueError:
proxy_port = None
if (
proxy_parts.scheme not in {"http", "https"}
or not proxy_parts.hostname
or proxy_port is None
or not 1 <= proxy_port <= 65_535
or proxy_parts.username
or proxy_parts.password
or proxy_parts.path not in {"", "/"}
or proxy_parts.query
or proxy_parts.fragment
):
raise SystemExit("Set PROXY_SERVER to an HTTP or HTTPS host and port without credentials")
if not EXPECTED_MARKER:
raise SystemExit("EXPECTED_MARKER must not be empty")
options = ChromiumOptions(read_file=False).headless().auto_port()
options.set_proxy(PROXY_SERVER)
options.set_timeouts(base=10, page_load=20, script=10)
page = ChromiumPage(addr_or_opts=options)
def navigate(url: str) -> int:
loaded = page.get(url, show_errmsg=False, retry=0, timeout=20)
if not loaded:
return 0
status = page.run_js(
"return performance.getEntriesByType('navigation')[0]?.responseStatus || 0",
timeout=10,
)
return int(status or 0)
try:
if navigate(IP_CHECK_URL) != 200:
raise SystemExit("IP check did not return HTTP 200")
ip_payload = json.loads(page.run_js("return document.body.innerText", timeout=10))
observed_ip = ip_payload.get("origin")
if not isinstance(observed_ip, str):
raise SystemExit("IP check returned no origin value")
ipaddress.ip_address(observed_ip.strip())
target_status = navigate(TARGET_URL)
if target_status != 200:
raise SystemExit("Target did not return HTTP 200")
text = page.run_js(
f"return document.body.innerText.slice(0, {MAX_TEXT_CHARS})",
timeout=10,
)
if EXPECTED_MARKER not in text:
raise SystemExit("Required target marker was not found")
print({"exit_ip_present": True, "target_status": target_status, "content_valid": True})
except Exception as error:
raise SystemExit(f"Browser check failed ({type(error).__name__})") from None
finally:
page.quit(timeout=5, force=True)
Run the saved script with the environment variables set: python drissionpage-check.py.
The script prints this only after the IP echo returned HTTP 200 with a valid IPv4 or IPv6 address and the target returned HTTP 200 with the required marker. exit_ip_present means the echo value passed IP parsing; the address is not printed. target_status is the target document’s HTTP status, and content_valid means the marker was found in the inspected content. This line matches the successful task-owned local-fixture run; it is an example result, not a claim about a proxy provider or an external target.
{'exit_ip_present': True, 'target_status': 200, 'content_valid': True}
The example makes 2 explicit navigations and sets DrissionPage’s navigation retry count to 0 for each. Browser startup may make its own network calls, and this is not a global request budget or a control over browser subresources. The 20-second page-load limit does not bound startup or cleanup; set a worker deadline to bound total elapsed time. The 12,000-character cap applies to extracted page text after loading, not to downloaded response bytes.
| Proxy endpoint | DrissionPage setup | Result |
|---|---|---|
| HTTP or HTTPS without authentication | set_proxy("scheme://host:port") before startup |
Direct supported configuration |
| Upstream requires a username and password | Start a trusted local bridge that authenticates upstream; point DrissionPage to its local unauthenticated endpoint | Credentials stay out of the browser setting |
| SOCKS5 endpoint | Use only if the installed browser and endpoint support the required mode | Verify protocol behavior against the current browser contract |
The current DrissionPage startup options reference says set_proxy() is applied at browser startup and does not support username/password authentication. Do not put user:pass@ into that setting and assume it will work. A bridge is a separate process: bind it to loopback, read upstream secrets from a secret store, avoid logging its configuration, and stop it after the browser exits.
| Observation | Check next | What it establishes |
|---|---|---|
| Browser cannot start | Confirm Chrome is installed and available to DrissionPage | Startup failed before the route check |
| IP page times out | Verify endpoint scheme, host, port, and worker egress | The browser did not complete the IP check |
| Authentication challenge or proxy error | Confirm the endpoint is unauthenticated or use an authenticated bridge | set_proxy() does not supply proxy credentials |
Target status is not 200 |
Check the target response and permission boundary | A working proxy does not establish target access |
Status is 200, marker is absent |
Inspect rendered content and parser requirements | The response did not contain the required field |
For an HTTPS target, target TLS protects the browser-to-target connection. An http:// proxy does not encrypt the separate browser-to-proxy hop; https:// does when supported by the endpoint. An IP echo shows the address reported for that request only. It does not prove where a user is, what address the next request uses, or whether a target accepts the browser.
Use the proxy error 407 guide for challenge diagnosis or the sticky-session guide when a multi-step flow needs provider-supported session continuity.
Scale your workflows with the tools you already use. Rotating or sticky sessions up to 72 hours.
Compare seller APIs, licensed Amazon product data and proxy page checks by record, access scope and reuse rights.
Read guideChoose the right anti-detect browser proxy guide, map the shared verification steps, and keep account access separate from the network route.
Read guideOur picks for market research: ProxyLane for small, intermittent projects, plus options for regional tracking, monthly collection and managed extraction.
Read guide