Use a residential proxy in Scrapy: set meta proxy and run a first check

Set meta["proxy"] on Scrapy requests with console credentials (URL-encode them). This is not the same as a one-off requests call. Do not treat crawl concurrency as a product rate limit. Not for mainland China.

Set meta["proxy"] on Scrapy requests with console credentials (URL-encode them). This is not the same as a one-off requests call. Do not treat crawl concurrency as a product rate limit. Not for mainland China.

Copy protocol, host, port, and auth from the console, then put them on Scrapy requests. A common pattern is a full proxy URL in `request.meta["proxy"]`, which the default `HttpProxyMiddleware` honors. That is not the same as one `requests.get(..., proxies=...)`: a crawl issues many requests, and exit cadence follows the rotating or static product you bought—not a Scrapy setting that “turns into static.” One-off Python calls: Python residential proxy.

ZTProxy sells rotating residential (per GB) and static residential (per IP·month). Examples use fake placeholders—not production hosts. Authorized targets only. Not for mainland China.

What to have ready

Ready itemSource
Protocol, host, port, authConsole values only (not the fake placeholders)
Python and ScrapyYour local environment
Check URLA page you may access
Rotating or static orderRotating vs static

Placeholders (not production): host `proxy.example.invalid`, port `10000`, user `USER_EXAMPLE`, password `PASS_EXAMPLE_NOT_REAL`. Strings: proxy format. Protocol: HTTP / SOCKS5 setup. Commands follow Docs EN quickstart. Confirm the same credentials with curl before starting a crawl.

Recommended pattern: meta["proxy"]

URL-encode the username or password if it contains `@` or `:`. Do not invent country or session fields in the username. Do not assume you must install a “rotating middleware” unless your own scheduling needs it and you understand how it interacts with the product you ordered.

import os
from urllib.parse import quote
import scrapy

user = quote(os.environ.get("ZT_PROXY_USER", "USER_EXAMPLE"), safe="")
password = quote(os.environ.get("ZT_PROXY_PASS", "PASS_EXAMPLE_NOT_REAL"), safe="")
host = os.environ.get("ZT_PROXY_HOST", "proxy.example.invalid")
port = os.environ.get("ZT_PROXY_PORT", "10000")
PROXY = f"http://{user}:{password}@{host}:{port}"

class AuthorizedCheckSpider(scrapy.Spider):
    name = "authorized_check"

    def start_requests(self):
        yield scrapy.Request(
            "https://example.com",
            meta={"proxy": PROXY},
            callback=self.parse,
        )

    def parse(self, response):
        self.logger.info("status=%s", response.status)

`CONCURRENT_REQUESTS` and `DOWNLOAD_DELAY` are client pacing. They reduce pressure on the target and help you avoid turning retries into extra billed traffic. They are not a ZTProxy rate limit or SLA. Billing units: GB vs IP. Use SOCKS5 only when the console returns SOCKS and your downloader can speak SOCKS. Do not assume UDP is available.

Sessions and common issues

On rotating residential, later requests may see different exits; that is not automatically a failure. For a short-lived same exit, use sticky fields from the console; for a term-long address, use static. See sticky ≠ static.

SymptomCheck first
407Username/password, URL encoding, missing `meta["proxy"]`; order still valid
Some requests bypass the proxyProxy set only on the first Request; later `follow` calls dropped meta
Timeouts or unusually high trafficRetries repeatedly downloading failures; recheck credentials with curl first
Wrong regionThe order region; do not invent username syntax

Fuller symptom table: 407 and timeouts.

Compliance and scope

Collect only public or authorized targets you may access, and respect site rules. This is not a bypass tutorial. Prices follow the console and pricing (rotating about $0.40/GB, about $0.20/GB on a 100 TB full bundle; static about $1.50 shared and about $5 dedicated per IP/month). USDT/USDC available; Visa/Mastercard in application. Not for mainland China.

FAQ

How is this different from the requests page?

That page is a single HTTP call. This page is about putting the proxy on every Scrapy Request and not dropping meta on follow-up requests.

Do I have to enable HttpProxyMiddleware myself?

It is usually on by default. Check that a custom middleware has not disabled or overridden it.

Can I use the example host as-is?

No. Replace it with console values.

If I raise CONCURRENT_REQUESTS, is that a higher plan?

No. That is only client concurrency. Plans and billing follow the console. See GB vs IP.

Must I install a third-party rotating plugin?

No. Start with the console product (rotating or static) and the credentials it issues. Do not stack an unverified middleware just to look like rotation.

Can I use this to break a login wall?

No. Authorized targets only.

If I reuse the same proxy URL, do I keep the same IP?

Not necessarily, especially on rotating residential. Reusing a URL is not static.

Where are prices confirmed?

In the console and on pricing.

Next steps

  1. Test console credentials with curl.
  2. Set `meta["proxy"]` on the first request and on later ones.
  3. When you need to choose a product, open rotating or static.