|
| 1 | +# Using Rotators |
| 2 | + |
| 3 | +The `tls_requests` library is designed to be smart out of the box. By default, it automatically rotates through realistic headers and client identifiers to make your requests appear authentic and avoid detection. |
| 4 | + |
| 5 | +This guide explains how these default rotators work and how you can customize or disable them. |
| 6 | + |
| 7 | +* * * |
| 8 | + |
| 9 | +### Header Rotator |
| 10 | + |
| 11 | +**Default Behavior: Automatic Rotation** |
| 12 | + |
| 13 | +When you initialize a `Client` without specifying the `headers` parameter, it will **automatically rotate** through a built-in collection of header templates that mimic popular browsers like Chrome, Firefox, and Safari across different operating systems. |
| 14 | + |
| 15 | +```python |
| 16 | +import tls_requests |
| 17 | + |
| 18 | +# No extra configuration needed! |
| 19 | +# This client will automatically use a different, realistic header set for each request. |
| 20 | +with tls_requests.Client(headers=tls_requests.HeaderRotator()) as client: |
| 21 | + # Request 1 might have Chrome headers |
| 22 | + res1 = client.get("https://httpbin.org/headers") |
| 23 | + print(f"Request 1 UA: {res1.json()['headers']['User-Agent']}") |
| 24 | + |
| 25 | + # Request 2 might have Firefox headers |
| 26 | + res2 = client.get("https://httpbin.org/headers") |
| 27 | + print(f"Request 2 UA: {res2.json()['headers']['User-Agent']}") |
| 28 | +``` |
| 29 | + |
| 30 | +**How to Override the Default Behavior:** |
| 31 | + |
| 32 | +- **To rotate through your own list of headers**, pass a `list` of `dict`s: |
| 33 | + ```python |
| 34 | + my_headers = [{"User-Agent": "MyBot/1.0"}, {"User-Agent": "MyBot/2.0"}] |
| 35 | + client = tls_requests.Client(headers=my_headers) |
| 36 | + ``` |
| 37 | + |
| 38 | +- **To use a single, static set of headers (no rotation)**, pass a single `dict`: |
| 39 | + ```python |
| 40 | + static_headers = {"User-Agent": "Always-The-Same-Bot/1.0"} |
| 41 | + client = tls_requests.Client(headers=static_headers) |
| 42 | + ``` |
| 43 | + |
| 44 | +- **To completely disable default headers**, pass `None`: |
| 45 | + ```python |
| 46 | + # This client will not add any default headers (like User-Agent). |
| 47 | + client = tls_requests.Client(headers=None) |
| 48 | + ``` |
| 49 | + |
| 50 | +* * * |
| 51 | + |
| 52 | +### TLS Client Identifier Rotator |
| 53 | + |
| 54 | +**Default Behavior: Automatic Rotation** |
| 55 | + |
| 56 | +Similar to headers, the `Client` **defaults to rotating** through all supported client identifier profiles (e.g., `chrome_120`, `firefox_120`, `safari_16_0`, etc.). This changes your TLS fingerprint with every request, an advanced technique to evade sophisticated anti-bot systems. |
| 57 | + |
| 58 | +```python |
| 59 | +import tls_requests |
| 60 | + |
| 61 | +# This client automatically changes its TLS fingerprint for each request. |
| 62 | +with tls_requests.Client(client_identifier=tls_requests.TLSIdentifierRotator()) as client: |
| 63 | + # These two requests will have different TLS profiles. |
| 64 | + res1 = client.get("https://tls.browserleaks.com/json") |
| 65 | + res2 = client.get("https://tls.browserleaks.com/json") |
| 66 | +``` |
| 67 | + |
| 68 | +**How to Override the Default Behavior:** |
| 69 | + |
| 70 | +- **To rotate through a specific list of identifiers**, pass a `list` of strings: |
| 71 | + ```python |
| 72 | + my_identifiers = ["chrome_120", "safari_16_0"] |
| 73 | + client = tls_requests.Client(client_identifier=my_identifiers) |
| 74 | + ``` |
| 75 | + |
| 76 | +- **To use a single, static identifier**, pass a string: |
| 77 | + ```python |
| 78 | + client = tls_requests.Client(client_identifier="chrome_120") |
| 79 | + ``` |
| 80 | +- **To disable rotation and use the library's single default identifier**, pass `None`: |
| 81 | + ```python |
| 82 | + client = tls_requests.Client(client_identifier=None) |
| 83 | + ``` |
| 84 | + |
| 85 | +* * * |
| 86 | + |
| 87 | +### Proxy Rotator |
| 88 | + |
| 89 | +Unlike headers and client identifiers, proxy rotation is **not enabled by default**, as the library cannot provide a list of free proxies. You must provide your own list to enable this feature. |
| 90 | + |
| 91 | +To enable proxy rotation, pass a list of proxy strings to the `proxy` parameter. The library will automatically use a `weighted` strategy, prioritizing proxies that perform well. |
| 92 | + |
| 93 | +```python |
| 94 | +import tls_requests |
| 95 | + |
| 96 | +proxy_list = [ |
| 97 | + "http://user1:pass1@proxy.example.com:8080", |
| 98 | + "http://user2:pass2@proxy.example.com:8081", |
| 99 | + "socks5://proxy.example.com:8082", |
| 100 | + "proxy.example.com:8083", # (defaults to http) |
| 101 | + "http://user:pass@proxy.example.com:8084|1.0|US", # http://user:pass@host:port|weight|region |
| 102 | +] |
| 103 | + |
| 104 | +# Provide a list to enable proxy rotation. |
| 105 | +with tls_requests.Client(proxy=proxy_list) as client: |
| 106 | + response = client.get("https://httpbin.org/get") |
| 107 | +``` |
| 108 | + |
| 109 | +For more control, you can create a `ProxyRotator` instance with a specific strategy: |
| 110 | + |
| 111 | +```python |
| 112 | +from tls_requests.models.rotators import ProxyRotator |
| 113 | + |
| 114 | +rotator = ProxyRotator.from_file(proxy_list, strategy="round_robin") |
| 115 | + |
| 116 | +with tls_requests.Client(proxy=rotator) as client: |
| 117 | + response = client.get("https://httpbin.org/get") |
| 118 | +``` |
| 119 | + |
| 120 | +> **Note:** The `Client` automatically provides performance feedback (success/failure, latency) to the `ProxyRotator`, making the `weighted` strategy highly effective. |
| 121 | +
|
| 122 | +* * * |
| 123 | + |
| 124 | +### Asynchronous Support |
| 125 | + |
| 126 | +All rotator features, including the smart defaults, work identically with `AsyncClient`. |
| 127 | + |
| 128 | +```python |
| 129 | +import tls_requests |
| 130 | +import asyncio |
| 131 | + |
| 132 | +async def main(): |
| 133 | + # This async client automatically uses default header and identifier rotation. |
| 134 | + async with tls_requests.AsyncClient( |
| 135 | + headers=tls_requests.HeaderRotator(), |
| 136 | + client_identifier=tls_requests.TLSIdentifierRotator() |
| 137 | + ) as client: |
| 138 | + tasks = [client.get("https://httpbin.org/get") for _ in range(2)] |
| 139 | + responses = await asyncio.gather(*tasks) |
| 140 | + |
| 141 | + for i, r in enumerate(responses): |
| 142 | + print(f"Async Request {i+1} status: {r.status_code}") |
| 143 | + |
| 144 | +asyncio.run(main()) |
| 145 | +``` |
0 commit comments