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 guideRoute Ruby Net::HTTP through an HTTP or HTTPS proxy, keep credentials separate, close sessions cleanly, and validate the target response.

Quick answer: configure Ruby Net::HTTP with the proxy host and port, enable Transport Layer Security (TLS) for an HTTPS target, and bind proxy credentials at runtime. Accept only a bounded response with the expected status and content; CONNECT alone does not validate the target result.
net/http, uri, and OpenSSL from this runtime.Save the complete example as proxy_get.rb. Set PROXY_URL to the http:// or https:// proxy host and port without user information. When authentication is required, inject both PROXY_USER and PROXY_PASSWORD; Net::HTTP.new passes them to the proxy separately from the target URL. Defaults use https://example.com/ and Example Domain; TARGET_URL and EXPECTED_MARKER allow an authorized test target. The response body is capped at 1 MiB and no retry is attempted.
Warning: First send one bounded request to a permitted test target and confirm its status and expected content; leave production jobs disabled until that check passes. For Basic proxy authentication, an http:// proxy exposes the login to observers on the client-to-proxy network path. CONNECT only establishes the tunnel; TLS to the target encrypts application traffic carried inside it, not the earlier proxy login. Ruby 3.4 can use TLS to an https:// proxy endpoint with certificate verification; enable that only when the proxy supports it. Keep credentials in a secret manager or runtime binding, rotate them if exposed, and check account usage after unexpected traffic.
Net::HTTP.new accepts the target address and port, followed by the proxy address, proxy port, username, and password. The example keeps PROXY_URL free of userinfo and passes optional credentials as separate runtime bindings. Replace the bracketed placeholders with values supplied through a secret store; do not commit literal credentials:
PROXY_URL=http://proxy.example:3128
PROXY_USER=<PROXY_USER>
PROXY_PASSWORD=<PROXY_PASSWORD>
use_ssl below enables TLS to the target after the proxy connection is established; it does not enable TLS to the proxy. The separate final p_use_ssl argument to Net::HTTP.new enables TLS to an https:// proxy. Use that option only when the provider supports an HTTPS proxy endpoint and its certificate validates.
Save this as proxy_get.rb. The example bounds connection open at 5 seconds and individual read/write operations at 10 seconds; the proxy timeout guide explains why these socket limits do not define one total job deadline. It accepts only 200 OK and rejects proxy 407:
require 'net/http'
require 'openssl'
require 'uri'
MAX_BODY_BYTES = 1 << 20
def required_env(name)
value = ENV[name].to_s.strip
raise "missing required environment binding: #{name}" if value.empty?
value
end
def read_response(http, target)
request = Net::HTTP::Get.new(target)
status = nil
body = +''
http.request(request) do |response|
status = response.code.to_i
if status == 407
raise 'proxy authentication or CONNECT negotiation returned HTTP 407'
end
response.read_body do |chunk|
if body.bytesize + chunk.bytesize > MAX_BODY_BYTES
raise 'response body exceeded local cap'
end
body << chunk
end
end
[status, body]
end
begin
target = URI(ENV.fetch('TARGET_URL', 'https://example.com/'))
rescue URI::InvalidURIError
warn 'TARGET_URL is invalid'
exit 1
end
unless %w[http https].include?(target.scheme) && !target.host.nil? && target.user.nil? && target.password.nil?
warn 'TARGET_URL must be an HTTP or HTTPS URL without credentials'
exit 1
end
expected_marker = ENV.fetch('EXPECTED_MARKER', 'Example Domain')
raise 'EXPECTED_MARKER must be non-empty' if expected_marker.empty?
begin
proxy = URI(required_env('PROXY_URL'))
rescue URI::InvalidURIError
warn 'PROXY_URL is not a valid URI'
exit 1
end
unless %w[http https].include?(proxy.scheme) && !proxy.host.nil? && proxy.user.nil? && proxy.password.nil?
raise 'PROXY_URL must be an HTTP or HTTPS proxy URL without credentials'
end
proxy_user = ENV['PROXY_USER']
proxy_password = ENV['PROXY_PASSWORD']
if proxy_user.nil? != proxy_password.nil? || (!proxy_user.nil? && (proxy_user.empty? || proxy_password.empty?))
raise 'PROXY_USER and PROXY_PASSWORD must be supplied together and non-empty'
end
http = Net::HTTP.new(
target.host,
target.port,
proxy.host,
proxy.port,
proxy_user,
proxy_password,
nil,
proxy.scheme == 'https'
)
http.use_ssl = target.scheme == 'https'
http.open_timeout = 5
http.read_timeout = 10
http.write_timeout = 10
http.max_retries = 0
begin
http.start do |session|
status, body = read_response(session, target)
raise 'target returned a non-accepted HTTP status' unless status == 200
raise 'target marker was absent' unless body.include?(expected_marker)
puts "status=#{status} marker=present"
end
rescue Net::OpenTimeout, Net::ReadTimeout, Net::WriteTimeout, SocketError, EOFError,
Errno::ECONNRESET, Errno::ECONNREFUSED, Errno::ETIMEDOUT,
OpenSSL::SSL::SSLError, Net::HTTPBadResponse, Net::HTTPFatalError, Net::ProtocolError
warn 'request failed in transport or proxy negotiation'
exit 1
end
Expected output for a successful response:
status=200 marker=present
The Net::HTTP.start block closes the connection when it exits. open_timeout covers opening the connection to the proxy. read_timeout and write_timeout apply to individual socket operations, not the total request duration. The response block rejects a 407 before reading its body, then bounds accepted body data at 1 MiB. With Ruby 3.4.11, an HTTPS CONNECT 407 raised a transport exception before a response object; the example emits a generic message to avoid logging proxy details. Malformed URI, TLS, and CONNECT failures exit with a generic message; the proxy URI and exception details never reach output.
This core example uses one attempt. If a worker adds retries for an idempotent GET, classify the failure first, honor a valid rate-limit Retry-After instruction, and keep a job-level deadline. DNS, TLS, connection, configuration, and proxy-authentication failures should stop immediately because repeating an invalid password or an unreachable endpoint does not repair the route.
Use an application-level contract rather than counting a successful request call:
input: permitted HTTPS target + HTTP proxy host/port + expected marker
output: status=200, marker present, body <= 1 MiB, session closed
The marker stands for the required application field or schema. A target can return a valid HTTP status with an error page, login form, or challenge; reject content that fails the parser contract. A Net::HTTP session is bound to one host and port. To check a trusted IP endpoint on another host, create a separate Net::HTTP instance for that host with the same proxy configuration, TLS verification, and timeout limits; send no target credentials. A provider may assign a different exit to the new connection, so check its documented session policy separately. The IP response describes only that check request, not the earlier target connection.
| Observation | Boundary | Next decision |
|---|---|---|
| Proxy URL has credentials or an unsupported scheme | Local configuration | Remove userinfo and use a documented HTTP proxy endpoint |
| Open/read/TLS exception before a response | Client, proxy, or CONNECT | Check proxy host, port, certificate, and reachability; do not retry blindly |
407 |
Proxy authentication | Repair proxy credentials or entitlement; keep them away from target headers |
401 or 403 after CONNECT |
Target policy | Check target login, permission, or target-side rules |
429 |
Target rate limit | Follow the rate-limit and Retry-After guide and reduce request rate; do not change exits to evade the limit |
| 3xx redirect | Target response | Inspect Location and permit the destination before sending a new request |
502, 503, or 504 |
Temporary gateway or target response | Defer or retry only under an explicit policy that honors Retry-After |
| HTTP 200 with no marker | Application validation | Reject the result and inspect the content or parser |
| Body exceeds 1 MiB | Local resource policy | Reject or define another bounded streaming rule |
For the same phase-by-phase view in a terminal, read the curl proxy guide. The proxy client settings guide covers cases where an application-specific route differs from the operating system.
When moving the example into a worker, preserve the configured proxy scheme, timeouts, and status/body checks before the job accepts a record.
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