Rotating proxy pool for Scrapy, Playwright and requests — health tracking, ban detection, sticky sessions. Zero dependencies.
Project description
proxyspin
Rotating proxy pool for Scrapy, Playwright and requests — with health tracking, ban detection, sticky sessions and a built-in list checker. Zero required dependencies, pure stdlib.
pip install proxyspin
Why another one? The classic scrapy-rotating-proxies hasn't been updated in years and is Scrapy-only. proxyspin is one small pool you can share across Scrapy spiders, Playwright contexts and plain requests code, with the same health model everywhere.
Features
- One pool, three integrations — Scrapy middleware, Playwright helper,
requestssession. - Rotation strategies —
round_robin,random,sticky(same proxy per domain/account/worker until it dies). - Health model — a proxy failing N times in a row is benched with exponential backoff and returns automatically; a success resets its streak.
- Ban detection — configurable HTTP codes (403/407/429 by default) count as proxy failures and trigger a retry through the next proxy.
- Any list format —
scheme://user:pass@host:port,host:port,host:port:user:pass,user:pass@host:port; load from a list, a file or a provider URL. - CLI checker —
proxyspin check proxies.txttests the whole list concurrently and can write the alive ones out.
Quickstart
The pool
from proxyspin import ProxyPool
pool = ProxyPool.from_file("proxies.txt", strategy="round_robin")
# or inline:
pool = ProxyPool(["http://user:pass@gate1.example.com:8000", "10.0.0.2:8000"])
# or straight from your provider's export endpoint:
pool = ProxyPool.from_url("https://provider.example.com/api/my-list.txt")
proxy = pool.get() # -> Proxy; proxy.url is ready to use
pool.mark_failed(proxy) # bench it after repeated failures
pool.mark_ok(proxy) # reset its failure streak
Scrapy
# settings.py
DOWNLOADER_MIDDLEWARES = {
"proxyspin.scrapy_middleware.ProxySpinMiddleware": 610,
}
PROXYSPIN_FILE = "proxies.txt"
PROXYSPIN_STRATEGY = "sticky" # one proxy per target host
PROXYSPIN_BAN_CODES = [403, 429] # these responses rotate the proxy
PROXYSPIN_MAX_RETRIES = 3
Per-request overrides: set request.meta["proxy"] to pin a proxy, meta["proxyspin_disabled"] = True to skip proxying, meta["proxyspin_key"] to control stickiness.
Playwright
from playwright.sync_api import sync_playwright
from proxyspin import ProxyPool
from proxyspin.playwright_helper import proxy_settings
pool = ProxyPool.from_file("proxies.txt", strategy="sticky")
with sync_playwright() as p:
browser = p.chromium.launch()
for account in accounts:
context = browser.new_context(proxy=proxy_settings(pool, key=account.id))
# each account keeps its own IP for the whole session
requests
from proxyspin import ProxyPool
from proxyspin.requests_adapter import RotatingSession
session = RotatingSession(ProxyPool.from_file("proxies.txt"))
print(session.get("https://httpbin.org/ip").json()) # new IP per call
Check a list
$ proxyspin check proxies.txt --workers 100 --alive-out alive.txt
OK 45.155.10.4:8000 612 ms HTTP 200
DEAD 91.10.77.2:3128 TimeoutError
...
118/200 alive
wrote 118 proxies to alive.txt
Providers
proxyspin works with any proxy source: your own servers, free lists, or commercial providers. Example with GProxy residential/mobile gateways (rotation happens server-side, so a pool of one entry per gateway is enough — use sticky if you need session pinning):
pool = ProxyPool([
"http://USER:PASS@gate.gproxy.net:8000", # residential, rotating
])
Any other provider works the same way — put its gateway or IP list into the pool.
Health model in one paragraph
Every proxy starts healthy. mark_failed increments its failure streak; when the streak reaches max_failures (default 2) the proxy is benched for cooldown * 2**overshoot seconds (default base 60 s, capped at 1 h), then automatically rejoins rotation. mark_ok resets the streak. The Scrapy middleware and RotatingSession call these for you based on exceptions and ban codes; with Playwright you call them yourself since only your code knows what a "ban" looks like for your flow.
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file proxyspin-0.1.0.tar.gz.
File metadata
- Download URL: proxyspin-0.1.0.tar.gz
- Upload date:
- Size: 10.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
152cd15367ecf8f9bbe4c159a0b6c4faa5f310175ddfc1d64906bfdbb9e1ae65
|
|
| MD5 |
81cff8043b8a4af791802b5c269ee7d8
|
|
| BLAKE2b-256 |
66f23001bd2b9c1aae8b36418bba972a6e2b31629d864c213b636663c1c36236
|
File details
Details for the file proxyspin-0.1.0-py3-none-any.whl.
File metadata
- Download URL: proxyspin-0.1.0-py3-none-any.whl
- Upload date:
- Size: 13.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d7b8550895b41f3919bff3147e23cf1ea4637d5a3e51b0a1c698c667d1a27344
|
|
| MD5 |
2e5cdcdbb7e0612d9e2e15a5d0b84cf8
|
|
| BLAKE2b-256 |
38b8ad053ebe5863904d1cda433aff33b02d30c1759472906a50728ad7273621
|