Skip to content

Repository files navigation

Python Proxy Rotation + CAPTCHA Session Lab

Python proxy session decision lab

tests python license

A fixture-first Python lab for deciding when to keep a proxy session, when a transport-only rotation is safe, when to honor Retry-After, and when an explicitly detected CAPTCHA may enter one bounded CapSolver recovery step.

English · 简体中文 · 日本語 · Español · Português · 한국어

Introduction

Generic rotation loops often treat 403, 407, 429, timeouts, and CAPTCHA pages as interchangeable reasons to switch IPs. They are different failure classes:

  • 429 is an origin rate-limit signal. Respect its cooldown instead of assuming another IP grants permission to continue.
  • 407 is a proxy configuration or authentication problem.
  • A proxy connect timeout can justify one rotation for a stateless request, but rotating a stateful browser or form session can invalidate cookies and server-side state.
  • 401 or 403 alone does not prove that a supported CAPTCHA exists.
  • A CAPTCHA result belongs to the proxy, cookie jar, User-Agent, origin, purpose, and authorization context used to create it.

This repository turns those distinctions into tested decisions. CapSolver appears only in the explicitly classified, authorized challenge branch.

Decision model

Observation Default action Rotate? CapSolver?
Expected record in a 2xx response Accept No No
429 Too Many Requests Honor Retry-After and cool down No No
407 Proxy Authentication Required Stop and fix configuration No No
Proxy transport failure, stateless request Rotate once within budget Once No
Proxy transport failure, stateful request Stop to preserve session context No No
Transient 5xx response Retry once with the same context No No
401/403 without explicit challenge classification Stop and review access No No
Explicit supported challenge with authorization Request one bounded recovery No Once

The 429 behavior follows RFC 6585, which allows an origin to communicate a wait interval with Retry-After. The session model follows the Requests Session documentation: sessions persist cookies and other parameters across requests.

Architecture

response or transport error
          │
          ▼
  explicit classifier
          │
          ├── 429 ───────────────► cool down
          ├── 407 / 401 / plain 403 ► stop and inspect
          ├── proxy transport ───► rotate only if stateless + budget remains
          ├── 5xx ───────────────► retry same session once
          └── typed challenge ───► authorization + context fingerprint
                                             │
                                             ▼
                                one CapSolver recovery request
                                             │
                          matching context? ─┴─ yes: return once and verify data
                                      no: stop

Quick start

Requires Python 3.11 or newer. Tests and examples use fixtures and make no external requests.

python -m venv .venv
source .venv/bin/activate
python -m pip install -e .
python -m unittest discover -s tests -v
python scripts/smoke_test.py
python examples/run_lab.py

Expected smoke output:

SMOKE PASSED: 429 cooled down; matching challenge recovered once; replay stopped

Core objects

SessionContext records non-secret identifiers for the active request context:

from proxy_captcha_lab import SessionContext

context = SessionContext(
    origin="https://qa.example.test",
    proxy_id="sticky-session-a",
    cookie_jar_hash="cookie-fixture-v1",
    user_agent="session-lab/0.1",
    authorization_ref="QA-42",
)

Store a digest or opaque cookie-jar identifier, not raw cookies. SessionContext.fingerprint changes if the proxy, cookie digest, User-Agent, origin, purpose, or authorization reference changes.

Observation keeps failure classification explicit:

from proxy_captcha_lab import Observation

rate_limited = Observation(status_code=429, retry_after_seconds=30)
plain_forbidden = Observation(status_code=403)
typed_challenge = Observation(status_code=403, challenge_type="supported-demo")

The lab never infers a CAPTCHA from an HTTP status alone. Production detection must be based on a supported challenge type observed in target-owner-approved code.

Bounded recovery

RecoveryCoordinator checks the decision budget and compares the result's context fingerprint with the active session before returning it:

from proxy_captcha_lab import FixtureGateway, RecoveryCoordinator

coordinator = RecoveryCoordinator(FixtureGateway())
decision = coordinator.handle(typed_challenge, context, stateful=True)
print(decision.action)

The fixture gateway proves the orchestration without sending a token or API key. To build a real authorized adapter, construct task fields from the current CapSolver createTask contract and poll only according to the getTaskResult contract. Page-specific application remains the target owner's responsibility.

What is deliberately out of scope

  • Proxy acquisition, free-proxy lists, or provider recommendations.
  • Automatic rotation after rate limits or access denials.
  • Fingerprint spoofing, challenge concealment, or access-control evasion.
  • Raw cookie, token, credential, or browser-profile storage.
  • Site-specific token injection or unsupported challenge types.
  • Unbounded retries, concurrency, or collection.

Test coverage

The suite verifies:

  1. Retry-After is honored without rotation.
  2. Plain 403 responses do not trigger CAPTCHA handling.
  3. Proxy authentication failures stop.
  4. Stateful transport failures preserve context and stop.
  5. Stateless transport failures rotate at most once.
  6. 5xx responses retry once on the same context.
  7. Missing authorization blocks recovery.
  8. Matching recovery context returns once.
  9. Mismatched context is rejected.
  10. Changing the proxy changes the session fingerprint.

Responsible use

Use this repository only for public data, systems you own, or targets covered by explicit written authorization. Follow applicable terms, access policies, privacy rules, request limits, and retention requirements. A CAPTCHA-solving capability does not grant permission to access private, restricted, sensitive, or unauthorized data.

Keep request rates bounded, retain only the evidence needed for debugging, redact credentials and cookies, and stop when the business record is still absent after the approved recovery attempt.

Repository structure

src/proxy_captcha_lab/   Classifier, policy, coordinator, and fixture gateway
tests/                   Offline unit tests
examples/                Three-observation decision walkthrough
scripts/                 Deterministic smoke test
research/                Topic deduplication and source verification
docs/zh-CN/              Chinese project summary

Contributing and security

Read CONTRIBUTING.md before changing decision semantics. Report sensitive problems according to SECURITY.md; never put API keys, proxy credentials, cookies, solution payloads, or private target URLs in an issue.

FAQ

Does this repository rotate real proxies?

No. It tests when rotation would be permitted by policy; it does not acquire proxies or make live proxy requests.

Does every 403 response require CAPTCHA handling?

No. A 403 can represent authorization, policy, configuration, or other access failures. The lab requires an explicit supported challenge classification.

Why not rotate after every 429?

A 429 communicates that the origin is rate limiting requests. The safe default is to honor the cooldown and reduce request pressure, not to treat another IP as permission to continue.

Can I replace the fixture gateway with a live CapSolver client?

Yes, for an authorized workflow. Keep the same context binding and attempt budget, use only current official task contracts, and verify the intended business record after the result is applied.

Is this an official proxy rotator or CapSolver SDK?

No. This is an independent, educational lab maintained as a CapSolver integration example; it is not a proxy product or replacement SDK.

Conclusion

This fixture-first lab keeps proxy transport decisions, origin rate limits, access denials, and typed challenges separate. It preserves stateful session affinity, binds every approved recovery to an auditable context fingerprint, and permits at most one authorized CapSolver recovery.

Maintainer Note

Developer sharing CapSolver integration examples.

License

MIT

About

Fixture-first Python lab for proxy retry decisions, session affinity, and bounded CAPTCHA recovery context.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages