Skip to content

Scrapy Proxy Setup: Request Meta, Middleware and Environment Variables

Scrapy has a built-in proxy middleware, so a proxy can be set per request, for the whole spider or from the environment. This guide shows each way, the settings that keep a crawl considerate, and how to confirm the proxy is used.

The proxy meta key

The Scrapy documentation describes HttpProxyMiddleware as the component that sets the HTTP proxy for requests through the proxy meta value of a Request object. You can set that key yourself, to a value like http://some_proxy_server:port or http://username:password@some_proxy_server:port. The docs add that the per-request value takes precedence over the environment variables and that it ignores no_proxy.

The proxy meta key: example

import scrapy

class IpSpider(scrapy.Spider):
    name = "ip"

    async def start(self):
        yield scrapy.Request(
            "https://ipinfo.io/json",
            meta={"proxy": "http://USERNAME:PASSWORD@proxy-host:port"},
        )

    def parse(self, response):
        yield response.json()

Replace USERNAME, PASSWORD, proxy-host and port with the values of your proxy.

One proxy for every request

To avoid repeating the meta key, set it in a downloader middleware. The documentation says a downloader middleware is activated through the DOWNLOADER_MIDDLEWARES setting, where each class path has an order number, and that process_request() is called for each request that goes through it.

One proxy for every request: example

# myproject/middlewares.py
class ProxyMiddleware:
    def process_request(self, request):
        request.meta.setdefault("proxy", "http://USERNAME:PASSWORD@proxy-host:port")
        return None

Example only: replace the placeholder values with your own.

One proxy for every request: example

# settings.py
DOWNLOADER_MIDDLEWARES = {
    "myproject.middlewares.ProxyMiddleware": 543,
}

Read the credentials from an environment variable or a secrets file instead of writing them in the code. Check the process_request() signature in the documentation of the Scrapy version you run.

Environment variables

HttpProxyMiddleware obeys, like Python's urllib.request, the http_proxy, https_proxy and no_proxy environment variables. Set them before you start the crawl and you do not need to change any spider code.

Environment variables: example

export http_proxy="http://USERNAME:PASSWORD@proxy-host:port"
export https_proxy="http://USERNAME:PASSWORD@proxy-host:port"
scrapy crawl ip

Special characters such as @ and : in a password must be percent-encoded in a proxy URL. See the [proxy address, port and login guide](/guides/proxy-address-port-login/).

HTTP or SOCKS

The Scrapy documentation says that a SOCKS proxy URL such as socks5://username:password@some_proxy_server:port can be used only if the download handler supports it, and it names the httpx-based handler as the built-in one that does, while the other built-in handlers do not. The same page notes that proxy URLs usually use the http:// scheme. For a default Scrapy project, use an HTTP proxy. If you need SOCKS5, check which download handler you use and read the handler's documentation first.

Check that the proxy is used

Run the spider above and read the country and org fields in the response from https://ipinfo.io/json; the proxy location guide explains how to read them. If you see your own address, the meta key was not set on that request, or the environment variables were set after the crawl started. Add the middleware so every request has the key.

Keep the crawl considerate

A proxy changes the address a site sees, but the site's rules still apply. Scrapy has settings for this. The settings documentation says ROBOTSTXT_OBEY makes Scrapy respect robots.txt policies, and that it is enabled in the settings.py generated by the scrapy startproject command. DOWNLOAD_DELAY sets the minimum seconds between two consecutive requests to the same domain and is meant to avoid hitting servers too hard, and CONCURRENT_REQUESTS_PER_DOMAIN limits simultaneous requests to a domain. The AutoThrottle extension adjusts delays dynamically, using download latency, to reach a target concurrency per remote site. Read the target site's terms before you crawl it.

Keep the crawl considerate: example

# settings.py
ROBOTSTXT_OBEY = True
DOWNLOAD_DELAY = 1
CONCURRENT_REQUESTS_PER_DOMAIN = 2
AUTOTHROTTLE_ENABLED = True

These values are a starting point; choose numbers that suit the site and your task.

Common errors

A 407 status means the proxy did not accept the username and password: copy them again and check the encoding, then see the authentication required guide. Connection errors and timeouts usually mean a wrong host, port or scheme; the connection failed guide lists the checks. The documentation describes RetryMiddleware as retrying requests that fail for temporary reasons such as a connection timeout or an HTTP 500 error, so a few failures in the log are not always a proxy problem. If you collect pages with plain HTTP calls instead of Scrapy, see the Python requests guide.

How to do it with Proxy302

Any of these setups only needs the host, port, username and password of a Proxy302 proxy. Rotating residential traffic is billed per GB and the exit country is set when you generate the proxy; HTTP is on port 2222 of proxy.proxy302.com. A static ISP IP stays fixed for the whole lease term and does not rotate. The table shows exits in 7 countries from our latest hourly check; the probe sends its request to ChatGPT, which is only an example target. Details are on the rotating residential page and in the proxy location guide.

Measured exits: ChatGPT from 7 countries

Measured exits: ChatGPT from 7 countries
ItemCityNetwork (ISP)ASN
United StatesBaton Rouge, LouisianaVerizon BusinessAS6167
United KingdomBirkenhead, EnglandVirgin Media LimitedAS5089
GermanyHannover, Lower Saxonyhtp GmbHAS13045
JapanSaitama, SaitamaJCOM Co., Ltd.AS9824
SingaporeYishun New Town, SingaporeSingtel Fibre BroadbandAS9506
BrazilSilvianópolis, Minas Geraisintertel telecomunicacao LTDAAS268801
IndonesiaJakarta, JakartaPT Mahawira Nusantara GrupAS151576

Hourly check of the Proxy302 probe, 28 October 2026, 14:56 UTC: one request to ChatGPT per country through a dynamic residential exit, using the public Proxy302 entry. Only the first three octets of an IP are public. One sample per country, not an average; later checks will differ.

How to do it with Proxy302: steps

  1. Step 1

    Open the rotating residential page, choose the line, and keep Protocol on HTTP or choose SOCKS5, then click Review cost and generate.

  2. Step 2

    Open My assets (the console page that holds everything you bought) and copy HOST, PORT, USERNAME and PASSWORD. The Connect page shows a ready example with your own endpoint.

  3. Step 3

    Enter the details in the browser or tool you are setting up.

  4. Step 4

    Confirm the exit with https://ipinfo.io/json through the proxy.

  5. Step 5

    From mainland China, start the helper tool from the Connect page first and keep it open while you use the proxy.

Prices and limits

The Budget line costs US$1.50 per GB, US$1.35 per GB in a 100 GB package and US$1.20 per GB at 300 GB. There is no free trial, and the smallest purchase is 1 GB. Which exit locations are available changes daily.

FAQ

Which proxy URL format does Scrapy accept?

The documentation gives http://some_proxy_server:port and http://username:password@some_proxy_server:port as examples.

Does Scrapy support SOCKS5 proxies?

The documentation says a SOCKS proxy URL works only if the download handler supports it, and lists the httpx-based handler as the built-in one that does.

Does the meta proxy value respect no_proxy?

No. The documentation says the per-request proxy meta value takes precedence over the environment variables and ignores no_proxy.

Does a proxy make Scrapy ignore robots.txt?

No. ROBOTSTXT_OBEY is a separate Scrapy setting, and a proxy does not change it.

Reference links

6
  1. Scrapy documentation: Downloader Middleware, HttpProxyMiddleware and RetryMiddleware

    Official documentation · Confirmed on:

    Read on 28 October 2026 (documentation version 2.19.0): the proxy meta key, http_proxy/https_proxy/no_proxy, URL formats with credentials, precedence of the meta value, SOCKS depending on the download handler, DOWNLOADER_MIDDLEWARES and process_request(), and RetryMiddleware.

  2. Scrapy documentation: Requests and Responses

    Official documentation · Confirmed on:

    Read on 28 October 2026: the Request meta dictionary, the proxy meta key and the async start() method of a spider.

  3. Scrapy documentation: Settings

    Official documentation · Confirmed on:

    Read on 28 October 2026: ROBOTSTXT_OBEY (enabled in the settings.py created by startproject), DOWNLOAD_DELAY and CONCURRENT_REQUESTS_PER_DOMAIN.

  4. Scrapy documentation: AutoThrottle extension

    Official documentation · Confirmed on:

    Read on 28 October 2026: the extension adjusts delays dynamically from download latency to reach AUTOTHROTTLE_TARGET_CONCURRENCY per remote site.

  5. Proxy302 product facts and price list

    Product observation · Confirmed on:

    Product facts file of the site (values checked against the console, the backend and the price table on 18-19 October 2026): products, prices in US$ (1 PTC = US$1), lease terms, protocols and ports, countries, quantity limits, no free trial.

  6. Proxy302 hourly connectivity check

    Product observation · Confirmed on:

    Public JSON of the probe at proxy302.com/live/connectivity/chatgpt.json, read 28 October 2026, 14:56 UTC: one request per exit country through a dynamic residential exit; exit city, ASN, network and response time.

Ready to try it?

Create an account, top up once, then pick rotating residential, static ISP or datacenter IPs and have one running in your browser within minutes.