notify-tls-client 0.1.6__py3-none-any.whl → 2.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- notify_tls_client/__init__.py +2 -2
- notify_tls_client/config/__init__.py +18 -0
- notify_tls_client/config/client_config.py +76 -0
- notify_tls_client/config/client_configuration.py +237 -0
- notify_tls_client/config/recovery_config.py +66 -0
- notify_tls_client/config/rotation_config.py +56 -0
- notify_tls_client/core/client/__init__.py +1 -6
- notify_tls_client/core/client/decorators.py +200 -90
- notify_tls_client/core/client_identifiers_manager.py +44 -0
- notify_tls_client/core/notifytlsclient.py +271 -146
- notify_tls_client/core/proxiesmanager/__init__.py +1 -1
- notify_tls_client/core/proxiesmanager/proxiesmanager.py +79 -67
- notify_tls_client/core/proxiesmanager/proxiesmanagerloader.py +33 -33
- notify_tls_client/tls_client/__init__.py +14 -14
- notify_tls_client/tls_client/__version__.py +10 -10
- notify_tls_client/tls_client/cffi.py +40 -62
- notify_tls_client/tls_client/cookies.py +456 -456
- notify_tls_client/tls_client/dependencies/{tls-client-xgo-1.11.0-darwin-arm64.dylib → tls-client-darwin-amd64-1.12.0.dylib} +0 -0
- notify_tls_client/tls_client/dependencies/tls-client-linux-arm64-1.12.0.so +0 -0
- notify_tls_client/tls_client/dependencies/{tls-client-xgo-1.11.0-linux-amd64.so → tls-client-linux-ubuntu-amd64-1.12.0.so} +0 -0
- notify_tls_client/tls_client/dependencies/{tls-client-windows-1.11.0-64.dll → tls-client-windows-64-1.12.0.dll} +0 -0
- notify_tls_client/tls_client/exceptions.py +2 -2
- notify_tls_client/tls_client/response.py +84 -78
- notify_tls_client/tls_client/sessions.py +524 -513
- notify_tls_client/tls_client/settings.py +69 -69
- notify_tls_client/tls_client/structures.py +74 -74
- notify_tls_client-2.0.0.dist-info/METADATA +38 -0
- notify_tls_client-2.0.0.dist-info/RECORD +32 -0
- {notify_tls_client-0.1.6.dist-info → notify_tls_client-2.0.0.dist-info}/WHEEL +1 -1
- notify_tls_client-0.1.6.dist-info/METADATA +0 -16
- notify_tls_client-0.1.6.dist-info/RECORD +0 -25
- {notify_tls_client-0.1.6.dist-info → notify_tls_client-2.0.0.dist-info}/top_level.txt +0 -0
notify_tls_client/__init__.py
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
from .core.notifytlsclient import NotifyTLSClient
|
|
2
|
-
from .tls_client import Session
|
|
1
|
+
from .core.notifytlsclient import NotifyTLSClient
|
|
2
|
+
from .tls_client import Session
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Módulo de configuração para NotifyTLSClient.
|
|
3
|
+
|
|
4
|
+
Fornece classes de configuração especializadas para organizar
|
|
5
|
+
os parâmetros do cliente TLS de forma mais limpa e reutilizável.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from .rotation_config import RotationConfig
|
|
9
|
+
from .recovery_config import RecoveryConfig
|
|
10
|
+
from .client_config import ClientConfig
|
|
11
|
+
from .client_configuration import ClientConfiguration
|
|
12
|
+
|
|
13
|
+
__all__ = [
|
|
14
|
+
'RotationConfig',
|
|
15
|
+
'RecoveryConfig',
|
|
16
|
+
'ClientConfig',
|
|
17
|
+
'ClientConfiguration',
|
|
18
|
+
]
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Configurações do cliente TLS (identifiers, headers, protocolos).
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from dataclasses import dataclass, field
|
|
6
|
+
from typing import Optional
|
|
7
|
+
|
|
8
|
+
from notify_tls_client.tls_client.settings import ClientIdentifiers
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@dataclass
|
|
12
|
+
class ClientConfig:
|
|
13
|
+
"""
|
|
14
|
+
Configurações relacionadas ao cliente TLS e fingerprinting.
|
|
15
|
+
|
|
16
|
+
Attributes:
|
|
17
|
+
client_identifiers: Lista de client identifiers para rotação.
|
|
18
|
+
Identifiers disponíveis incluem chrome_133, firefox_120, safari_17_0, etc.
|
|
19
|
+
Se apenas um identifier for fornecido, não haverá rotação.
|
|
20
|
+
Default: ["chrome_133"]
|
|
21
|
+
|
|
22
|
+
default_headers: Headers padrão a serem enviados em todas as requisições.
|
|
23
|
+
Pode ser sobrescrito por requisição individual.
|
|
24
|
+
Default: None (usa headers padrão do tls-client)
|
|
25
|
+
|
|
26
|
+
disable_http3: Se True, força o uso de HTTP/2 ou HTTP/1.1, desabilitando HTTP/3.
|
|
27
|
+
Útil para ambientes que não suportam QUIC.
|
|
28
|
+
Default: False
|
|
29
|
+
|
|
30
|
+
debug_mode: Se True, habilita logs de debug detalhados.
|
|
31
|
+
IMPORTANTE: Pode vazar informações sensíveis nos logs.
|
|
32
|
+
Default: False
|
|
33
|
+
|
|
34
|
+
Examples:
|
|
35
|
+
>>> # Configuração padrão
|
|
36
|
+
>>> config = ClientConfig()
|
|
37
|
+
|
|
38
|
+
>>> # Múltiplos identifiers para stealth
|
|
39
|
+
>>> config = ClientConfig(
|
|
40
|
+
... client_identifiers=["chrome_133", "firefox_120", "safari_17_0"]
|
|
41
|
+
... )
|
|
42
|
+
|
|
43
|
+
>>> # Headers customizados
|
|
44
|
+
>>> config = ClientConfig(
|
|
45
|
+
... default_headers={
|
|
46
|
+
... "User-Agent": "Mozilla/5.0...",
|
|
47
|
+
... "Accept-Language": "pt-BR,pt;q=0.9"
|
|
48
|
+
... }
|
|
49
|
+
... )
|
|
50
|
+
|
|
51
|
+
>>> # Forçar HTTP/2
|
|
52
|
+
>>> config = ClientConfig(disable_http3=True)
|
|
53
|
+
"""
|
|
54
|
+
|
|
55
|
+
client_identifiers: list[ClientIdentifiers] = field(default_factory=lambda: ["chrome_133"])
|
|
56
|
+
default_headers: Optional[dict] = None
|
|
57
|
+
disable_http3: bool = False
|
|
58
|
+
debug_mode: bool = False
|
|
59
|
+
|
|
60
|
+
def __post_init__(self):
|
|
61
|
+
"""Valida os parâmetros de configuração."""
|
|
62
|
+
if not self.client_identifiers:
|
|
63
|
+
raise ValueError("client_identifiers não pode ser vazio")
|
|
64
|
+
|
|
65
|
+
if len(self.client_identifiers) != len(set(self.client_identifiers)):
|
|
66
|
+
raise ValueError("client_identifiers contém duplicatas")
|
|
67
|
+
|
|
68
|
+
# Valida default_headers se fornecido
|
|
69
|
+
if self.default_headers is not None:
|
|
70
|
+
if not isinstance(self.default_headers, dict):
|
|
71
|
+
raise ValueError("default_headers deve ser um dicionário")
|
|
72
|
+
|
|
73
|
+
# Valida que keys são strings
|
|
74
|
+
for key in self.default_headers.keys():
|
|
75
|
+
if not isinstance(key, str):
|
|
76
|
+
raise ValueError(f"Header key inválido: {key}. Deve ser string")
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Configuração completa do NotifyTLSClient com factory methods para casos de uso comuns.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from dataclasses import dataclass, field
|
|
6
|
+
from typing import Optional
|
|
7
|
+
|
|
8
|
+
from notify_tls_client.core.proxiesmanager import ProxiesManager
|
|
9
|
+
from .rotation_config import RotationConfig
|
|
10
|
+
from .recovery_config import RecoveryConfig
|
|
11
|
+
from .client_config import ClientConfig
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@dataclass
|
|
15
|
+
class ClientConfiguration:
|
|
16
|
+
"""
|
|
17
|
+
Configuração completa para NotifyTLSClient.
|
|
18
|
+
|
|
19
|
+
Agrupa todas as configurações específicas em um único objeto para
|
|
20
|
+
simplificar a criação e reutilização de configurações.
|
|
21
|
+
|
|
22
|
+
Attributes:
|
|
23
|
+
proxies_manager: Gerenciador de proxies para rotação automática.
|
|
24
|
+
Default: None (sem proxies)
|
|
25
|
+
|
|
26
|
+
rotation: Configurações de rotação de proxies e client identifiers.
|
|
27
|
+
Default: RotationConfig com valores padrão
|
|
28
|
+
|
|
29
|
+
recovery: Configurações de recuperação automática.
|
|
30
|
+
Default: RecoveryConfig com valores padrão
|
|
31
|
+
|
|
32
|
+
client: Configurações do cliente TLS.
|
|
33
|
+
Default: ClientConfig com valores padrão
|
|
34
|
+
|
|
35
|
+
Examples:
|
|
36
|
+
>>> # Configuração padrão
|
|
37
|
+
>>> config = ClientConfiguration()
|
|
38
|
+
|
|
39
|
+
>>> # Configuração customizada
|
|
40
|
+
>>> config = ClientConfiguration(
|
|
41
|
+
... proxies_manager=ProxiesManager([...]),
|
|
42
|
+
... rotation=RotationConfig(requests_limit_same_proxy=10),
|
|
43
|
+
... recovery=RecoveryConfig(
|
|
44
|
+
... instantiate_new_client_on_forbidden_response=True,
|
|
45
|
+
... status_codes_to_forbidden_response_handle=[403, 429]
|
|
46
|
+
... ),
|
|
47
|
+
... client=ClientConfig(
|
|
48
|
+
... client_identifiers=["chrome_133", "firefox_120"]
|
|
49
|
+
... )
|
|
50
|
+
... )
|
|
51
|
+
|
|
52
|
+
>>> # Usando factory method
|
|
53
|
+
>>> config = ClientConfiguration.aggressive(proxies_manager)
|
|
54
|
+
"""
|
|
55
|
+
|
|
56
|
+
proxies_manager: Optional[ProxiesManager] = None
|
|
57
|
+
rotation: RotationConfig = field(default_factory=RotationConfig)
|
|
58
|
+
recovery: RecoveryConfig = field(default_factory=RecoveryConfig)
|
|
59
|
+
client: ClientConfig = field(default_factory=ClientConfig)
|
|
60
|
+
|
|
61
|
+
@classmethod
|
|
62
|
+
def aggressive(cls, proxies_manager: Optional[ProxiesManager] = None) -> 'ClientConfiguration':
|
|
63
|
+
"""
|
|
64
|
+
Configuração agressiva: rotação rápida e recuperação automática completa.
|
|
65
|
+
|
|
66
|
+
Ideal para cenários de scraping intensivo onde detectar e contornar
|
|
67
|
+
bloqueios rapidamente é crítico.
|
|
68
|
+
|
|
69
|
+
Características:
|
|
70
|
+
- Troca proxy a cada 10 requisições
|
|
71
|
+
- Troca client identifier a cada 50 requisições
|
|
72
|
+
- Recuperação automática em erros e respostas proibidas
|
|
73
|
+
- Troca client identifier em respostas proibidas
|
|
74
|
+
- Monitora status codes 403, 429 e 503
|
|
75
|
+
|
|
76
|
+
Args:
|
|
77
|
+
proxies_manager: Gerenciador de proxies (obrigatório para rotação)
|
|
78
|
+
|
|
79
|
+
Returns:
|
|
80
|
+
ClientConfiguration configurado para modo agressivo
|
|
81
|
+
|
|
82
|
+
Example:
|
|
83
|
+
>>> tls = NotifyTLSClient(ClientConfiguration.aggressive(proxies))
|
|
84
|
+
"""
|
|
85
|
+
return cls(
|
|
86
|
+
proxies_manager=proxies_manager,
|
|
87
|
+
rotation=RotationConfig(
|
|
88
|
+
requests_limit_same_proxy=10,
|
|
89
|
+
requests_limit_same_client_identifier=50,
|
|
90
|
+
random_tls_extension_order=True
|
|
91
|
+
),
|
|
92
|
+
recovery=RecoveryConfig(
|
|
93
|
+
instantiate_new_client_on_forbidden_response=True,
|
|
94
|
+
instantiate_new_client_on_exception=True,
|
|
95
|
+
change_client_identifier_on_forbidden_response=True,
|
|
96
|
+
status_codes_to_forbidden_response_handle=[403, 429, 503]
|
|
97
|
+
),
|
|
98
|
+
client=ClientConfig(
|
|
99
|
+
client_identifiers=["chrome_133", "firefox_120", "safari_17_0"]
|
|
100
|
+
)
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
@classmethod
|
|
104
|
+
def stealth(cls, proxies_manager: Optional[ProxiesManager] = None) -> 'ClientConfiguration':
|
|
105
|
+
"""
|
|
106
|
+
Configuração stealth: foco em evitar detecção através de diversidade.
|
|
107
|
+
|
|
108
|
+
Ideal para cenários onde ser discreto é mais importante que velocidade,
|
|
109
|
+
utilizando múltiplos client identifiers e randomização.
|
|
110
|
+
|
|
111
|
+
Características:
|
|
112
|
+
- Múltiplos client identifiers (Chrome, Firefox, Safari, Edge)
|
|
113
|
+
- Ordem de extensões TLS randomizada
|
|
114
|
+
- Rotação moderada de proxies (100 requisições)
|
|
115
|
+
- Rotação de client identifier a cada 30 requisições
|
|
116
|
+
- Recuperação básica apenas para erros críticos
|
|
117
|
+
|
|
118
|
+
Args:
|
|
119
|
+
proxies_manager: Gerenciador de proxies (opcional mas recomendado)
|
|
120
|
+
|
|
121
|
+
Returns:
|
|
122
|
+
ClientConfiguration configurado para modo stealth
|
|
123
|
+
|
|
124
|
+
Example:
|
|
125
|
+
>>> tls = NotifyTLSClient(ClientConfiguration.stealth(proxies))
|
|
126
|
+
"""
|
|
127
|
+
return cls(
|
|
128
|
+
proxies_manager=proxies_manager,
|
|
129
|
+
rotation=RotationConfig(
|
|
130
|
+
requests_limit_same_proxy=100,
|
|
131
|
+
requests_limit_same_client_identifier=30,
|
|
132
|
+
random_tls_extension_order=True
|
|
133
|
+
),
|
|
134
|
+
recovery=RecoveryConfig(
|
|
135
|
+
instantiate_new_client_on_forbidden_response=False,
|
|
136
|
+
instantiate_new_client_on_exception=True,
|
|
137
|
+
change_client_identifier_on_forbidden_response=False,
|
|
138
|
+
status_codes_to_forbidden_response_handle=[403]
|
|
139
|
+
),
|
|
140
|
+
client=ClientConfig(
|
|
141
|
+
client_identifiers=[
|
|
142
|
+
"chrome_133",
|
|
143
|
+
"firefox_120",
|
|
144
|
+
"safari_17_0",
|
|
145
|
+
"safari_ios_16_0"
|
|
146
|
+
]
|
|
147
|
+
)
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
@classmethod
|
|
151
|
+
def simple(cls, proxies_manager: Optional[ProxiesManager] = None) -> 'ClientConfiguration':
|
|
152
|
+
"""
|
|
153
|
+
Configuração simples: apenas rotação básica de proxies.
|
|
154
|
+
|
|
155
|
+
Ideal para uso geral onde não há necessidade de evasão agressiva,
|
|
156
|
+
mantendo a simplicidade e confiabilidade.
|
|
157
|
+
|
|
158
|
+
Características:
|
|
159
|
+
- Client identifier único (Chrome 133)
|
|
160
|
+
- Rotação de proxy padrão (1000 requisições)
|
|
161
|
+
- Sem rotação de client identifier
|
|
162
|
+
- Sem recuperação automática
|
|
163
|
+
- Monitora apenas status 403
|
|
164
|
+
|
|
165
|
+
Args:
|
|
166
|
+
proxies_manager: Gerenciador de proxies (opcional)
|
|
167
|
+
|
|
168
|
+
Returns:
|
|
169
|
+
ClientConfiguration configurado para modo simples
|
|
170
|
+
|
|
171
|
+
Example:
|
|
172
|
+
>>> tls = NotifyTLSClient(ClientConfiguration.simple())
|
|
173
|
+
"""
|
|
174
|
+
return cls(
|
|
175
|
+
proxies_manager=proxies_manager,
|
|
176
|
+
rotation=RotationConfig(
|
|
177
|
+
requests_limit_same_proxy=1000,
|
|
178
|
+
requests_limit_same_client_identifier=-1,
|
|
179
|
+
random_tls_extension_order=False
|
|
180
|
+
),
|
|
181
|
+
recovery=RecoveryConfig(
|
|
182
|
+
instantiate_new_client_on_forbidden_response=False,
|
|
183
|
+
instantiate_new_client_on_exception=False,
|
|
184
|
+
change_client_identifier_on_forbidden_response=False,
|
|
185
|
+
status_codes_to_forbidden_response_handle=[403]
|
|
186
|
+
),
|
|
187
|
+
client=ClientConfig(
|
|
188
|
+
client_identifiers=["chrome_133"]
|
|
189
|
+
)
|
|
190
|
+
)
|
|
191
|
+
|
|
192
|
+
@classmethod
|
|
193
|
+
def mobile(cls, proxies_manager: Optional[ProxiesManager] = None, platform: str = "android") -> 'ClientConfiguration':
|
|
194
|
+
"""
|
|
195
|
+
Configuração mobile: simula dispositivos móveis.
|
|
196
|
+
|
|
197
|
+
Ideal para APIs ou sites que têm comportamento diferente para mobile.
|
|
198
|
+
|
|
199
|
+
Características:
|
|
200
|
+
- Client identifiers mobile (Android ou iOS)
|
|
201
|
+
- Rotação moderada
|
|
202
|
+
- Recuperação automática em erros
|
|
203
|
+
|
|
204
|
+
Args:
|
|
205
|
+
proxies_manager: Gerenciador de proxies (opcional)
|
|
206
|
+
platform: "android" ou "ios"
|
|
207
|
+
|
|
208
|
+
Returns:
|
|
209
|
+
ClientConfiguration configurado para modo mobile
|
|
210
|
+
|
|
211
|
+
Example:
|
|
212
|
+
>>> tls = NotifyTLSClient(ClientConfiguration.mobile(platform="ios"))
|
|
213
|
+
"""
|
|
214
|
+
if platform.lower() == "android":
|
|
215
|
+
identifiers = ["okhttp4_android_13", "okhttp4_android_12"]
|
|
216
|
+
elif platform.lower() == "ios":
|
|
217
|
+
identifiers = ["safari_ios_16_0", "safari_ios_15_6"]
|
|
218
|
+
else:
|
|
219
|
+
raise ValueError(f"Platform inválida: {platform}. Use 'android' ou 'ios'")
|
|
220
|
+
|
|
221
|
+
return cls(
|
|
222
|
+
proxies_manager=proxies_manager,
|
|
223
|
+
rotation=RotationConfig(
|
|
224
|
+
requests_limit_same_proxy=50,
|
|
225
|
+
requests_limit_same_client_identifier=100,
|
|
226
|
+
random_tls_extension_order=True
|
|
227
|
+
),
|
|
228
|
+
recovery=RecoveryConfig(
|
|
229
|
+
instantiate_new_client_on_forbidden_response=True,
|
|
230
|
+
instantiate_new_client_on_exception=True,
|
|
231
|
+
change_client_identifier_on_forbidden_response=False,
|
|
232
|
+
status_codes_to_forbidden_response_handle=[403, 429]
|
|
233
|
+
),
|
|
234
|
+
client=ClientConfig(
|
|
235
|
+
client_identifiers=identifiers
|
|
236
|
+
)
|
|
237
|
+
)
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Configurações de recuperação automática em caso de erros e respostas proibidas.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from dataclasses import dataclass, field
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
@dataclass
|
|
9
|
+
class RecoveryConfig:
|
|
10
|
+
"""
|
|
11
|
+
Configurações para controlar o comportamento de recuperação automática.
|
|
12
|
+
|
|
13
|
+
Attributes:
|
|
14
|
+
instantiate_new_client_on_forbidden_response: Se True, cria uma nova sessão TLS
|
|
15
|
+
quando receber um status code configurado como "proibido".
|
|
16
|
+
Default: False
|
|
17
|
+
|
|
18
|
+
instantiate_new_client_on_exception: Se True, cria uma nova sessão TLS
|
|
19
|
+
quando ocorrer uma exceção durante a requisição.
|
|
20
|
+
Default: False
|
|
21
|
+
|
|
22
|
+
change_client_identifier_on_forbidden_response: Se True, além de criar uma nova
|
|
23
|
+
sessão, também troca o client identifier quando receber resposta proibida.
|
|
24
|
+
Requer instantiate_new_client_on_forbidden_response=True para ter efeito.
|
|
25
|
+
Default: False
|
|
26
|
+
|
|
27
|
+
status_codes_to_forbidden_response_handle: Lista de status codes HTTP que devem
|
|
28
|
+
acionar os mecanismos de recuperação automática.
|
|
29
|
+
Default: [403]
|
|
30
|
+
|
|
31
|
+
Examples:
|
|
32
|
+
>>> # Recuperação agressiva
|
|
33
|
+
>>> config = RecoveryConfig(
|
|
34
|
+
... instantiate_new_client_on_forbidden_response=True,
|
|
35
|
+
... instantiate_new_client_on_exception=True,
|
|
36
|
+
... change_client_identifier_on_forbidden_response=True,
|
|
37
|
+
... status_codes_to_forbidden_response_handle=[403, 429, 503]
|
|
38
|
+
... )
|
|
39
|
+
|
|
40
|
+
>>> # Sem recuperação automática
|
|
41
|
+
>>> config = RecoveryConfig()
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
instantiate_new_client_on_forbidden_response: bool = False
|
|
45
|
+
instantiate_new_client_on_exception: bool = False
|
|
46
|
+
change_client_identifier_on_forbidden_response: bool = False
|
|
47
|
+
status_codes_to_forbidden_response_handle: list[int] = field(default_factory=lambda: [403])
|
|
48
|
+
|
|
49
|
+
def __post_init__(self):
|
|
50
|
+
"""Valida os parâmetros de configuração."""
|
|
51
|
+
if not self.status_codes_to_forbidden_response_handle:
|
|
52
|
+
raise ValueError("status_codes_to_forbidden_response_handle não pode ser vazio")
|
|
53
|
+
|
|
54
|
+
for code in self.status_codes_to_forbidden_response_handle:
|
|
55
|
+
if not isinstance(code, int) or code < 100 or code > 599:
|
|
56
|
+
raise ValueError(f"Status code inválido: {code}. Deve estar entre 100 e 599")
|
|
57
|
+
|
|
58
|
+
# Aviso sobre configuração inconsistente
|
|
59
|
+
if self.change_client_identifier_on_forbidden_response and not self.instantiate_new_client_on_forbidden_response:
|
|
60
|
+
import warnings
|
|
61
|
+
warnings.warn(
|
|
62
|
+
"change_client_identifier_on_forbidden_response=True não terá efeito "
|
|
63
|
+
"porque instantiate_new_client_on_forbidden_response=False. "
|
|
64
|
+
"Considere habilitar ambos.",
|
|
65
|
+
UserWarning
|
|
66
|
+
)
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Configurações de rotação de proxies e client identifiers.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from dataclasses import dataclass
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
@dataclass
|
|
9
|
+
class RotationConfig:
|
|
10
|
+
"""
|
|
11
|
+
Configurações para controlar a rotação automática de proxies e client identifiers.
|
|
12
|
+
|
|
13
|
+
Attributes:
|
|
14
|
+
requests_limit_same_proxy: Número máximo de requisições com o mesmo proxy.
|
|
15
|
+
Use -1 para desabilitar rotação automática por limite.
|
|
16
|
+
Default: 1000
|
|
17
|
+
|
|
18
|
+
requests_limit_same_client_identifier: Número máximo de requisições com o mesmo
|
|
19
|
+
client identifier. Use -1 para desabilitar rotação automática por limite.
|
|
20
|
+
Default: -1 (desabilitado)
|
|
21
|
+
|
|
22
|
+
random_tls_extension_order: Se True, randomiza a ordem das extensões TLS
|
|
23
|
+
para dificultar fingerprinting.
|
|
24
|
+
Default: True
|
|
25
|
+
|
|
26
|
+
Examples:
|
|
27
|
+
>>> # Rotação agressiva
|
|
28
|
+
>>> config = RotationConfig(
|
|
29
|
+
... requests_limit_same_proxy=10,
|
|
30
|
+
... requests_limit_same_client_identifier=50
|
|
31
|
+
... )
|
|
32
|
+
|
|
33
|
+
>>> # Sem rotação automática
|
|
34
|
+
>>> config = RotationConfig(
|
|
35
|
+
... requests_limit_same_proxy=-1,
|
|
36
|
+
... requests_limit_same_client_identifier=-1
|
|
37
|
+
... )
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
requests_limit_same_proxy: int = 1000
|
|
41
|
+
requests_limit_same_client_identifier: int = -1
|
|
42
|
+
random_tls_extension_order: bool = True
|
|
43
|
+
|
|
44
|
+
def __post_init__(self):
|
|
45
|
+
"""Valida os parâmetros de configuração."""
|
|
46
|
+
if self.requests_limit_same_proxy < -1:
|
|
47
|
+
raise ValueError("requests_limit_same_proxy deve ser >= -1")
|
|
48
|
+
|
|
49
|
+
if self.requests_limit_same_client_identifier < -1:
|
|
50
|
+
raise ValueError("requests_limit_same_client_identifier deve ser >= -1")
|
|
51
|
+
|
|
52
|
+
if self.requests_limit_same_proxy == 0:
|
|
53
|
+
raise ValueError("requests_limit_same_proxy não pode ser 0 (use -1 para desabilitar)")
|
|
54
|
+
|
|
55
|
+
if self.requests_limit_same_client_identifier == 0:
|
|
56
|
+
raise ValueError("requests_limit_same_client_identifier não pode ser 0 (use -1 para desabilitar)")
|