Skip to main content

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, requests session.
  • Rotation strategiesround_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 formatscheme://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 checkerproxyspin check proxies.txt tests 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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

proxyspin-0.1.0.tar.gz (10.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

proxyspin-0.1.0-py3-none-any.whl (13.5 kB view details)

Uploaded Python 3

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

Hashes for proxyspin-0.1.0.tar.gz
Algorithm Hash digest
SHA256 152cd15367ecf8f9bbe4c159a0b6c4faa5f310175ddfc1d64906bfdbb9e1ae65
MD5 81cff8043b8a4af791802b5c269ee7d8
BLAKE2b-256 66f23001bd2b9c1aae8b36418bba972a6e2b31629d864c213b636663c1c36236

See more details on using hashes here.

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

Hashes for proxyspin-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 d7b8550895b41f3919bff3147e23cf1ea4637d5a3e51b0a1c698c667d1a27344
MD5 2e5cdcdbb7e0612d9e2e15a5d0b84cf8
BLAKE2b-256 38b8ad053ebe5863904d1cda433aff33b02d30c1759472906a50728ad7273621

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page