notify-tls-client 2.0.0__tar.gz → 2.0.1__tar.gz
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-2.0.1/PKG-INFO +338 -0
- notify_tls_client-2.0.1/README.md +302 -0
- {notify_tls_client-2.0.0 → notify_tls_client-2.0.1}/notify_tls_client/config/recovery_config.py +6 -1
- {notify_tls_client-2.0.0 → notify_tls_client-2.0.1}/notify_tls_client/core/client/decorators.py +52 -27
- {notify_tls_client-2.0.0 → notify_tls_client-2.0.1}/notify_tls_client/core/client_identifiers_manager.py +12 -9
- {notify_tls_client-2.0.0 → notify_tls_client-2.0.1}/notify_tls_client/core/notifytlsclient.py +31 -20
- {notify_tls_client-2.0.0 → notify_tls_client-2.0.1}/notify_tls_client/core/proxiesmanager/proxiesmanager.py +26 -12
- {notify_tls_client-2.0.0 → notify_tls_client-2.0.1}/notify_tls_client/tls_client/response.py +1 -0
- notify_tls_client-2.0.1/notify_tls_client.egg-info/PKG-INFO +338 -0
- {notify_tls_client-2.0.0 → notify_tls_client-2.0.1}/pyproject.toml +3 -3
- notify_tls_client-2.0.0/PKG-INFO +0 -38
- notify_tls_client-2.0.0/README.md +0 -2
- notify_tls_client-2.0.0/notify_tls_client.egg-info/PKG-INFO +0 -38
- {notify_tls_client-2.0.0 → notify_tls_client-2.0.1}/MANIFEST.in +0 -0
- {notify_tls_client-2.0.0 → notify_tls_client-2.0.1}/notify_tls_client/__init__.py +0 -0
- {notify_tls_client-2.0.0 → notify_tls_client-2.0.1}/notify_tls_client/config/__init__.py +0 -0
- {notify_tls_client-2.0.0 → notify_tls_client-2.0.1}/notify_tls_client/config/client_config.py +0 -0
- {notify_tls_client-2.0.0 → notify_tls_client-2.0.1}/notify_tls_client/config/client_configuration.py +0 -0
- {notify_tls_client-2.0.0 → notify_tls_client-2.0.1}/notify_tls_client/config/rotation_config.py +0 -0
- {notify_tls_client-2.0.0 → notify_tls_client-2.0.1}/notify_tls_client/core/__init__.py +0 -0
- {notify_tls_client-2.0.0 → notify_tls_client-2.0.1}/notify_tls_client/core/client/__init__.py +0 -0
- {notify_tls_client-2.0.0 → notify_tls_client-2.0.1}/notify_tls_client/core/proxiesmanager/__init__.py +0 -0
- {notify_tls_client-2.0.0 → notify_tls_client-2.0.1}/notify_tls_client/core/proxiesmanager/proxiesmanagerloader.py +0 -0
- {notify_tls_client-2.0.0 → notify_tls_client-2.0.1}/notify_tls_client/tls_client/__init__.py +0 -0
- {notify_tls_client-2.0.0 → notify_tls_client-2.0.1}/notify_tls_client/tls_client/__version__.py +0 -0
- {notify_tls_client-2.0.0 → notify_tls_client-2.0.1}/notify_tls_client/tls_client/cffi.py +0 -0
- {notify_tls_client-2.0.0 → notify_tls_client-2.0.1}/notify_tls_client/tls_client/cookies.py +0 -0
- {notify_tls_client-2.0.0 → notify_tls_client-2.0.1}/notify_tls_client/tls_client/dependencies/__init__.py +0 -0
- {notify_tls_client-2.0.0 → notify_tls_client-2.0.1}/notify_tls_client/tls_client/dependencies/tls-client-darwin-amd64-1.12.0.dylib +0 -0
- {notify_tls_client-2.0.0 → notify_tls_client-2.0.1}/notify_tls_client/tls_client/dependencies/tls-client-linux-arm64-1.12.0.so +0 -0
- {notify_tls_client-2.0.0 → notify_tls_client-2.0.1}/notify_tls_client/tls_client/dependencies/tls-client-linux-ubuntu-amd64-1.12.0.so +0 -0
- {notify_tls_client-2.0.0 → notify_tls_client-2.0.1}/notify_tls_client/tls_client/dependencies/tls-client-windows-64-1.12.0.dll +0 -0
- {notify_tls_client-2.0.0 → notify_tls_client-2.0.1}/notify_tls_client/tls_client/exceptions.py +0 -0
- {notify_tls_client-2.0.0 → notify_tls_client-2.0.1}/notify_tls_client/tls_client/sessions.py +0 -0
- {notify_tls_client-2.0.0 → notify_tls_client-2.0.1}/notify_tls_client/tls_client/settings.py +0 -0
- {notify_tls_client-2.0.0 → notify_tls_client-2.0.1}/notify_tls_client/tls_client/structures.py +0 -0
- {notify_tls_client-2.0.0 → notify_tls_client-2.0.1}/notify_tls_client.egg-info/SOURCES.txt +0 -0
- {notify_tls_client-2.0.0 → notify_tls_client-2.0.1}/notify_tls_client.egg-info/dependency_links.txt +0 -0
- {notify_tls_client-2.0.0 → notify_tls_client-2.0.1}/notify_tls_client.egg-info/requires.txt +0 -0
- {notify_tls_client-2.0.0 → notify_tls_client-2.0.1}/notify_tls_client.egg-info/top_level.txt +0 -0
- {notify_tls_client-2.0.0 → notify_tls_client-2.0.1}/setup.cfg +0 -0
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: notify-tls-client
|
|
3
|
+
Version: 2.0.1
|
|
4
|
+
Summary: Cliente HTTP avançado com TLS fingerprinting, rotação automática de proxies e recuperação inteligente para web scraping profissional
|
|
5
|
+
Author-email: Jeferson Albara <jeferson.albara@example.com>
|
|
6
|
+
Maintainer-email: Jeferson Albara <jeferson.albara@example.com>
|
|
7
|
+
License: MIT
|
|
8
|
+
Project-URL: Homepage, https://github.com/jefersonAlbara/notify-tls-client
|
|
9
|
+
Project-URL: Documentation, https://github.com/jefersonAlbara/notify-tls-client#readme
|
|
10
|
+
Project-URL: Repository, https://github.com/jefersonAlbara/notify-tls-client
|
|
11
|
+
Project-URL: Issues, https://github.com/jefersonAlbara/notify-tls-client/issues
|
|
12
|
+
Project-URL: Changelog, https://github.com/jefersonAlbara/notify-tls-client/blob/main/CHANGELOG.md
|
|
13
|
+
Keywords: tls-client,http-client,web-scraping,proxy-rotation,tls-fingerprinting,browser-emulation,http2,http3,requests,automation
|
|
14
|
+
Classifier: Development Status :: 4 - Beta
|
|
15
|
+
Classifier: Intended Audience :: Developers
|
|
16
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Topic :: Internet :: WWW/HTTP
|
|
21
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
22
|
+
Classifier: Topic :: Internet :: Proxy Servers
|
|
23
|
+
Classifier: Operating System :: OS Independent
|
|
24
|
+
Classifier: Typing :: Typed
|
|
25
|
+
Requires-Python: >=3.12
|
|
26
|
+
Description-Content-Type: text/markdown
|
|
27
|
+
Requires-Dist: dataclasses-json>=0.6.0
|
|
28
|
+
Requires-Dist: typing-extensions>=4.8.0
|
|
29
|
+
Requires-Dist: orjson>=3.9.0
|
|
30
|
+
Provides-Extra: dev
|
|
31
|
+
Requires-Dist: pytest>=7.4.0; extra == "dev"
|
|
32
|
+
Requires-Dist: pytest-cov>=4.1.0; extra == "dev"
|
|
33
|
+
Requires-Dist: black>=23.0.0; extra == "dev"
|
|
34
|
+
Requires-Dist: mypy>=1.5.0; extra == "dev"
|
|
35
|
+
Requires-Dist: ruff>=0.1.0; extra == "dev"
|
|
36
|
+
|
|
37
|
+
# Notify TLS Client
|
|
38
|
+
|
|
39
|
+
[](https://badge.fury.io/py/notify-tls-client)
|
|
40
|
+
[](https://pypi.org/project/notify-tls-client/)
|
|
41
|
+
[](https://opensource.org/licenses/MIT)
|
|
42
|
+
|
|
43
|
+
Cliente HTTP avançado em Python com suporte a TLS/SSL customizado, fingerprinting de navegadores e rotação automática de proxies. Construído sobre a biblioteca `tls-client` com funcionalidades adicionais para web scraping e automação resiliente.
|
|
44
|
+
|
|
45
|
+
## 🚀 Características Principais
|
|
46
|
+
|
|
47
|
+
- **Fingerprinting TLS Avançado**: Emula múltiplos navegadores (Chrome, Firefox, Safari, Edge, Mobile)
|
|
48
|
+
- **Rotação Automática**: Proxies e client identifiers com políticas configuráveis
|
|
49
|
+
- **Recuperação Automática**: Reconexão inteligente em erros e respostas proibidas
|
|
50
|
+
- **Thread-Safe**: Uso seguro em ambientes multi-threaded
|
|
51
|
+
- **Configuração Modular**: Sistema de configuração baseado em objetos reutilizáveis
|
|
52
|
+
- **Presets Prontos**: Configurações pré-definidas para casos de uso comuns
|
|
53
|
+
- **HTTP/3 Support**: Suporte opcional a QUIC/HTTP3
|
|
54
|
+
|
|
55
|
+
## 📦 Instalação
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
pip install notify-tls-client
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Requisitos
|
|
62
|
+
|
|
63
|
+
- Python >= 3.12
|
|
64
|
+
- Sistema operacional: Windows, macOS, Linux (x86_64, ARM64)
|
|
65
|
+
|
|
66
|
+
## 🎯 Quick Start
|
|
67
|
+
|
|
68
|
+
### Uso Básico
|
|
69
|
+
|
|
70
|
+
```python
|
|
71
|
+
from notify_tls_client import NotifyTLSClient
|
|
72
|
+
|
|
73
|
+
# Cliente com configuração padrão
|
|
74
|
+
client = NotifyTLSClient()
|
|
75
|
+
|
|
76
|
+
# Fazer requisição
|
|
77
|
+
response = client.get("https://api.example.com/data")
|
|
78
|
+
print(response.status_code)
|
|
79
|
+
print(response.json())
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Usando Presets (Recomendado)
|
|
83
|
+
|
|
84
|
+
```python
|
|
85
|
+
from notify_tls_client import NotifyTLSClient
|
|
86
|
+
from notify_tls_client.config import ClientConfiguration
|
|
87
|
+
from notify_tls_client.core.proxiesmanager import ProxiesManagerLoader
|
|
88
|
+
|
|
89
|
+
# Carregar proxies
|
|
90
|
+
proxies = ProxiesManagerLoader().from_txt("proxies.txt")
|
|
91
|
+
|
|
92
|
+
# Preset para scraping agressivo
|
|
93
|
+
config = ClientConfiguration.aggressive(proxies)
|
|
94
|
+
client = NotifyTLSClient(config)
|
|
95
|
+
|
|
96
|
+
# Fazer múltiplas requisições
|
|
97
|
+
for i in range(100):
|
|
98
|
+
response = client.get("https://example.com/api/endpoint")
|
|
99
|
+
print(f"Request {i}: {response.status_code}")
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Configuração Customizada
|
|
103
|
+
|
|
104
|
+
```python
|
|
105
|
+
from notify_tls_client import NotifyTLSClient
|
|
106
|
+
from notify_tls_client.config import (
|
|
107
|
+
ClientConfiguration,
|
|
108
|
+
RotationConfig,
|
|
109
|
+
RecoveryConfig,
|
|
110
|
+
ClientConfig
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
config = ClientConfiguration(
|
|
114
|
+
proxies_manager=proxies,
|
|
115
|
+
rotation=RotationConfig(
|
|
116
|
+
requests_limit_same_proxy=50,
|
|
117
|
+
requests_limit_same_client_identifier=200,
|
|
118
|
+
random_tls_extension_order=True
|
|
119
|
+
),
|
|
120
|
+
recovery=RecoveryConfig(
|
|
121
|
+
instantiate_new_client_on_forbidden_response=True,
|
|
122
|
+
instantiate_new_client_on_exception=True,
|
|
123
|
+
change_client_identifier_on_forbidden_response=True,
|
|
124
|
+
status_codes_to_forbidden_response_handle=[403, 429, 503]
|
|
125
|
+
),
|
|
126
|
+
client=ClientConfig(
|
|
127
|
+
client_identifiers=["chrome_133", "firefox_120", "safari_17_0"],
|
|
128
|
+
disable_http3=False,
|
|
129
|
+
debug_mode=False
|
|
130
|
+
)
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
client = NotifyTLSClient(config)
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## 📚 Presets Disponíveis
|
|
137
|
+
|
|
138
|
+
### Simple
|
|
139
|
+
Uso básico com rotação de proxies padrão.
|
|
140
|
+
```python
|
|
141
|
+
config = ClientConfiguration.simple(proxies)
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### Aggressive
|
|
145
|
+
Para scraping intensivo com recuperação automática completa.
|
|
146
|
+
```python
|
|
147
|
+
config = ClientConfiguration.aggressive(proxies)
|
|
148
|
+
```
|
|
149
|
+
- Troca proxy a cada 10 requisições
|
|
150
|
+
- Troca client identifier a cada 50 requisições
|
|
151
|
+
- Recuperação automática em erros e 403/429/503
|
|
152
|
+
- Múltiplos client identifiers
|
|
153
|
+
|
|
154
|
+
### Stealth
|
|
155
|
+
Foco em evitar detecção através de diversidade.
|
|
156
|
+
```python
|
|
157
|
+
config = ClientConfiguration.stealth(proxies)
|
|
158
|
+
```
|
|
159
|
+
- 4 client identifiers diferentes
|
|
160
|
+
- Ordem de extensões TLS randomizada
|
|
161
|
+
- Rotação moderada (100 req/proxy)
|
|
162
|
+
|
|
163
|
+
### Mobile
|
|
164
|
+
Simula dispositivos móveis.
|
|
165
|
+
```python
|
|
166
|
+
# Android
|
|
167
|
+
config = ClientConfiguration.mobile(proxies, platform="android")
|
|
168
|
+
|
|
169
|
+
# iOS
|
|
170
|
+
config = ClientConfiguration.mobile(proxies, platform="ios")
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
## 🔧 Funcionalidades Avançadas
|
|
174
|
+
|
|
175
|
+
### Rotação de Proxies
|
|
176
|
+
|
|
177
|
+
```python
|
|
178
|
+
from notify_tls_client.core.proxiesmanager import ProxiesManagerLoader
|
|
179
|
+
|
|
180
|
+
# Carregar de arquivo
|
|
181
|
+
proxies = ProxiesManagerLoader().from_txt("proxies.txt")
|
|
182
|
+
|
|
183
|
+
# Formato do arquivo (um por linha):
|
|
184
|
+
# host:port
|
|
185
|
+
# host:port:username:password
|
|
186
|
+
# http://username:password@host:port
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### Client Identifiers Suportados
|
|
190
|
+
|
|
191
|
+
**Desktop:**
|
|
192
|
+
- Chrome: `chrome_133`, `chrome_131`, `chrome_120`, etc.
|
|
193
|
+
- Firefox: `firefox_120`, `firefox_117`, `firefox_110`, etc.
|
|
194
|
+
- Safari: `safari_17_0`, `safari_16_0`, etc.
|
|
195
|
+
- Edge, Opera
|
|
196
|
+
|
|
197
|
+
**Mobile:**
|
|
198
|
+
- Android: `okhttp4_android_13`, `okhttp4_android_12`, etc.
|
|
199
|
+
- iOS: `safari_ios_16_0`, `safari_ios_15_6`, etc.
|
|
200
|
+
|
|
201
|
+
### Recuperação Automática
|
|
202
|
+
|
|
203
|
+
```python
|
|
204
|
+
config = ClientConfiguration(
|
|
205
|
+
recovery=RecoveryConfig(
|
|
206
|
+
# Criar nova sessão em respostas proibidas
|
|
207
|
+
instantiate_new_client_on_forbidden_response=True,
|
|
208
|
+
|
|
209
|
+
# Criar nova sessão em exceções
|
|
210
|
+
instantiate_new_client_on_exception=True,
|
|
211
|
+
|
|
212
|
+
# Trocar identifier em respostas proibidas
|
|
213
|
+
change_client_identifier_on_forbidden_response=True,
|
|
214
|
+
|
|
215
|
+
# Status codes que acionam recuperação
|
|
216
|
+
status_codes_to_forbidden_response_handle=[403, 429, 503]
|
|
217
|
+
)
|
|
218
|
+
)
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
### Headers Customizados
|
|
222
|
+
|
|
223
|
+
```python
|
|
224
|
+
config = ClientConfiguration(
|
|
225
|
+
client=ClientConfig(
|
|
226
|
+
default_headers={
|
|
227
|
+
"User-Agent": "Mozilla/5.0...",
|
|
228
|
+
"Accept-Language": "pt-BR,pt;q=0.9",
|
|
229
|
+
"Custom-Header": "value"
|
|
230
|
+
}
|
|
231
|
+
)
|
|
232
|
+
)
|
|
233
|
+
|
|
234
|
+
# Ou por requisição
|
|
235
|
+
response = client.get(
|
|
236
|
+
"https://example.com",
|
|
237
|
+
headers={"Authorization": "Bearer token"}
|
|
238
|
+
)
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
### Cookies
|
|
242
|
+
|
|
243
|
+
```python
|
|
244
|
+
# Obter todos os cookies
|
|
245
|
+
cookies = client.get_cookies()
|
|
246
|
+
|
|
247
|
+
# Obter cookie específico
|
|
248
|
+
value = client.get_cookie_by_name("session_id")
|
|
249
|
+
|
|
250
|
+
# Definir cookie
|
|
251
|
+
client.set_cookie("name", "value")
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
## 🔒 Thread Safety
|
|
255
|
+
|
|
256
|
+
A biblioteca é thread-safe e pode ser usada em ambientes multi-threaded:
|
|
257
|
+
|
|
258
|
+
```python
|
|
259
|
+
import concurrent.futures
|
|
260
|
+
|
|
261
|
+
client = NotifyTLSClient(ClientConfiguration.aggressive(proxies))
|
|
262
|
+
|
|
263
|
+
def make_request(url):
|
|
264
|
+
return client.get(url)
|
|
265
|
+
|
|
266
|
+
with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
|
|
267
|
+
urls = ["https://example.com"] * 100
|
|
268
|
+
results = list(executor.map(make_request, urls))
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
## 📊 Logging
|
|
272
|
+
|
|
273
|
+
```python
|
|
274
|
+
import logging
|
|
275
|
+
|
|
276
|
+
# Habilitar logs de debug
|
|
277
|
+
logging.basicConfig(level=logging.DEBUG)
|
|
278
|
+
|
|
279
|
+
# Ou configurar apenas para notify_tls_client
|
|
280
|
+
logger = logging.getLogger("notify_tls_client")
|
|
281
|
+
logger.setLevel(logging.DEBUG)
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
## 🛠️ Métodos HTTP Suportados
|
|
285
|
+
|
|
286
|
+
```python
|
|
287
|
+
# GET
|
|
288
|
+
response = client.get(url, params={"key": "value"})
|
|
289
|
+
|
|
290
|
+
# POST
|
|
291
|
+
response = client.post(url, json={"data": "value"})
|
|
292
|
+
response = client.post(url, data="form data")
|
|
293
|
+
|
|
294
|
+
# PUT
|
|
295
|
+
response = client.put(url, json={"data": "value"})
|
|
296
|
+
|
|
297
|
+
# PATCH
|
|
298
|
+
response = client.patch(url, json={"data": "value"})
|
|
299
|
+
|
|
300
|
+
# DELETE
|
|
301
|
+
response = client.delete(url)
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
## 📖 Documentação Completa
|
|
305
|
+
|
|
306
|
+
Para documentação detalhada sobre arquitetura, componentes internos e exemplos avançados, consulte:
|
|
307
|
+
- [CLAUDE.md](CLAUDE.md) - Guia completo de desenvolvimento
|
|
308
|
+
- [examples/](examples/) - Exemplos de código
|
|
309
|
+
|
|
310
|
+
## 🤝 Contribuindo
|
|
311
|
+
|
|
312
|
+
Contribuições são bem-vindas! Por favor, leia [CONTRIBUTING.md](CONTRIBUTING.md) para detalhes sobre nosso código de conduta e processo de submissão de pull requests.
|
|
313
|
+
|
|
314
|
+
## 📝 Changelog
|
|
315
|
+
|
|
316
|
+
Veja [CHANGELOG.md](CHANGELOG.md) para histórico de versões e mudanças.
|
|
317
|
+
|
|
318
|
+
## 📄 Licença
|
|
319
|
+
|
|
320
|
+
Este projeto está licenciado sob a Licença MIT - veja o arquivo [LICENSE](LICENSE) para detalhes.
|
|
321
|
+
|
|
322
|
+
## ⚠️ Aviso Legal
|
|
323
|
+
|
|
324
|
+
Esta biblioteca é fornecida apenas para fins educacionais e de pesquisa. O uso desta ferramenta para violar termos de serviço de websites, realizar scraping não autorizado ou qualquer atividade ilegal é de sua responsabilidade. Os desenvolvedores não se responsabilizam pelo uso indevido desta biblioteca.
|
|
325
|
+
|
|
326
|
+
## 🙏 Agradecimentos
|
|
327
|
+
|
|
328
|
+
- [tls-client](https://github.com/bogdanfinn/tls-client) - Biblioteca Go subjacente para TLS fingerprinting
|
|
329
|
+
- Comunidade Python por ferramentas e bibliotecas incríveis
|
|
330
|
+
|
|
331
|
+
## 📞 Suporte
|
|
332
|
+
|
|
333
|
+
- **Issues**: [GitHub Issues](https://github.com/jefersonAlbara/notify-tls-client/issues)
|
|
334
|
+
- **Discussões**: [GitHub Discussions](https://github.com/jefersonAlbara/notify-tls-client/discussions)
|
|
335
|
+
|
|
336
|
+
---
|
|
337
|
+
|
|
338
|
+
**Desenvolvido com ❤️ para a comunidade Python**
|
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
# Notify TLS Client
|
|
2
|
+
|
|
3
|
+
[](https://badge.fury.io/py/notify-tls-client)
|
|
4
|
+
[](https://pypi.org/project/notify-tls-client/)
|
|
5
|
+
[](https://opensource.org/licenses/MIT)
|
|
6
|
+
|
|
7
|
+
Cliente HTTP avançado em Python com suporte a TLS/SSL customizado, fingerprinting de navegadores e rotação automática de proxies. Construído sobre a biblioteca `tls-client` com funcionalidades adicionais para web scraping e automação resiliente.
|
|
8
|
+
|
|
9
|
+
## 🚀 Características Principais
|
|
10
|
+
|
|
11
|
+
- **Fingerprinting TLS Avançado**: Emula múltiplos navegadores (Chrome, Firefox, Safari, Edge, Mobile)
|
|
12
|
+
- **Rotação Automática**: Proxies e client identifiers com políticas configuráveis
|
|
13
|
+
- **Recuperação Automática**: Reconexão inteligente em erros e respostas proibidas
|
|
14
|
+
- **Thread-Safe**: Uso seguro em ambientes multi-threaded
|
|
15
|
+
- **Configuração Modular**: Sistema de configuração baseado em objetos reutilizáveis
|
|
16
|
+
- **Presets Prontos**: Configurações pré-definidas para casos de uso comuns
|
|
17
|
+
- **HTTP/3 Support**: Suporte opcional a QUIC/HTTP3
|
|
18
|
+
|
|
19
|
+
## 📦 Instalação
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
pip install notify-tls-client
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### Requisitos
|
|
26
|
+
|
|
27
|
+
- Python >= 3.12
|
|
28
|
+
- Sistema operacional: Windows, macOS, Linux (x86_64, ARM64)
|
|
29
|
+
|
|
30
|
+
## 🎯 Quick Start
|
|
31
|
+
|
|
32
|
+
### Uso Básico
|
|
33
|
+
|
|
34
|
+
```python
|
|
35
|
+
from notify_tls_client import NotifyTLSClient
|
|
36
|
+
|
|
37
|
+
# Cliente com configuração padrão
|
|
38
|
+
client = NotifyTLSClient()
|
|
39
|
+
|
|
40
|
+
# Fazer requisição
|
|
41
|
+
response = client.get("https://api.example.com/data")
|
|
42
|
+
print(response.status_code)
|
|
43
|
+
print(response.json())
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Usando Presets (Recomendado)
|
|
47
|
+
|
|
48
|
+
```python
|
|
49
|
+
from notify_tls_client import NotifyTLSClient
|
|
50
|
+
from notify_tls_client.config import ClientConfiguration
|
|
51
|
+
from notify_tls_client.core.proxiesmanager import ProxiesManagerLoader
|
|
52
|
+
|
|
53
|
+
# Carregar proxies
|
|
54
|
+
proxies = ProxiesManagerLoader().from_txt("proxies.txt")
|
|
55
|
+
|
|
56
|
+
# Preset para scraping agressivo
|
|
57
|
+
config = ClientConfiguration.aggressive(proxies)
|
|
58
|
+
client = NotifyTLSClient(config)
|
|
59
|
+
|
|
60
|
+
# Fazer múltiplas requisições
|
|
61
|
+
for i in range(100):
|
|
62
|
+
response = client.get("https://example.com/api/endpoint")
|
|
63
|
+
print(f"Request {i}: {response.status_code}")
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Configuração Customizada
|
|
67
|
+
|
|
68
|
+
```python
|
|
69
|
+
from notify_tls_client import NotifyTLSClient
|
|
70
|
+
from notify_tls_client.config import (
|
|
71
|
+
ClientConfiguration,
|
|
72
|
+
RotationConfig,
|
|
73
|
+
RecoveryConfig,
|
|
74
|
+
ClientConfig
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
config = ClientConfiguration(
|
|
78
|
+
proxies_manager=proxies,
|
|
79
|
+
rotation=RotationConfig(
|
|
80
|
+
requests_limit_same_proxy=50,
|
|
81
|
+
requests_limit_same_client_identifier=200,
|
|
82
|
+
random_tls_extension_order=True
|
|
83
|
+
),
|
|
84
|
+
recovery=RecoveryConfig(
|
|
85
|
+
instantiate_new_client_on_forbidden_response=True,
|
|
86
|
+
instantiate_new_client_on_exception=True,
|
|
87
|
+
change_client_identifier_on_forbidden_response=True,
|
|
88
|
+
status_codes_to_forbidden_response_handle=[403, 429, 503]
|
|
89
|
+
),
|
|
90
|
+
client=ClientConfig(
|
|
91
|
+
client_identifiers=["chrome_133", "firefox_120", "safari_17_0"],
|
|
92
|
+
disable_http3=False,
|
|
93
|
+
debug_mode=False
|
|
94
|
+
)
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
client = NotifyTLSClient(config)
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## 📚 Presets Disponíveis
|
|
101
|
+
|
|
102
|
+
### Simple
|
|
103
|
+
Uso básico com rotação de proxies padrão.
|
|
104
|
+
```python
|
|
105
|
+
config = ClientConfiguration.simple(proxies)
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Aggressive
|
|
109
|
+
Para scraping intensivo com recuperação automática completa.
|
|
110
|
+
```python
|
|
111
|
+
config = ClientConfiguration.aggressive(proxies)
|
|
112
|
+
```
|
|
113
|
+
- Troca proxy a cada 10 requisições
|
|
114
|
+
- Troca client identifier a cada 50 requisições
|
|
115
|
+
- Recuperação automática em erros e 403/429/503
|
|
116
|
+
- Múltiplos client identifiers
|
|
117
|
+
|
|
118
|
+
### Stealth
|
|
119
|
+
Foco em evitar detecção através de diversidade.
|
|
120
|
+
```python
|
|
121
|
+
config = ClientConfiguration.stealth(proxies)
|
|
122
|
+
```
|
|
123
|
+
- 4 client identifiers diferentes
|
|
124
|
+
- Ordem de extensões TLS randomizada
|
|
125
|
+
- Rotação moderada (100 req/proxy)
|
|
126
|
+
|
|
127
|
+
### Mobile
|
|
128
|
+
Simula dispositivos móveis.
|
|
129
|
+
```python
|
|
130
|
+
# Android
|
|
131
|
+
config = ClientConfiguration.mobile(proxies, platform="android")
|
|
132
|
+
|
|
133
|
+
# iOS
|
|
134
|
+
config = ClientConfiguration.mobile(proxies, platform="ios")
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## 🔧 Funcionalidades Avançadas
|
|
138
|
+
|
|
139
|
+
### Rotação de Proxies
|
|
140
|
+
|
|
141
|
+
```python
|
|
142
|
+
from notify_tls_client.core.proxiesmanager import ProxiesManagerLoader
|
|
143
|
+
|
|
144
|
+
# Carregar de arquivo
|
|
145
|
+
proxies = ProxiesManagerLoader().from_txt("proxies.txt")
|
|
146
|
+
|
|
147
|
+
# Formato do arquivo (um por linha):
|
|
148
|
+
# host:port
|
|
149
|
+
# host:port:username:password
|
|
150
|
+
# http://username:password@host:port
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### Client Identifiers Suportados
|
|
154
|
+
|
|
155
|
+
**Desktop:**
|
|
156
|
+
- Chrome: `chrome_133`, `chrome_131`, `chrome_120`, etc.
|
|
157
|
+
- Firefox: `firefox_120`, `firefox_117`, `firefox_110`, etc.
|
|
158
|
+
- Safari: `safari_17_0`, `safari_16_0`, etc.
|
|
159
|
+
- Edge, Opera
|
|
160
|
+
|
|
161
|
+
**Mobile:**
|
|
162
|
+
- Android: `okhttp4_android_13`, `okhttp4_android_12`, etc.
|
|
163
|
+
- iOS: `safari_ios_16_0`, `safari_ios_15_6`, etc.
|
|
164
|
+
|
|
165
|
+
### Recuperação Automática
|
|
166
|
+
|
|
167
|
+
```python
|
|
168
|
+
config = ClientConfiguration(
|
|
169
|
+
recovery=RecoveryConfig(
|
|
170
|
+
# Criar nova sessão em respostas proibidas
|
|
171
|
+
instantiate_new_client_on_forbidden_response=True,
|
|
172
|
+
|
|
173
|
+
# Criar nova sessão em exceções
|
|
174
|
+
instantiate_new_client_on_exception=True,
|
|
175
|
+
|
|
176
|
+
# Trocar identifier em respostas proibidas
|
|
177
|
+
change_client_identifier_on_forbidden_response=True,
|
|
178
|
+
|
|
179
|
+
# Status codes que acionam recuperação
|
|
180
|
+
status_codes_to_forbidden_response_handle=[403, 429, 503]
|
|
181
|
+
)
|
|
182
|
+
)
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### Headers Customizados
|
|
186
|
+
|
|
187
|
+
```python
|
|
188
|
+
config = ClientConfiguration(
|
|
189
|
+
client=ClientConfig(
|
|
190
|
+
default_headers={
|
|
191
|
+
"User-Agent": "Mozilla/5.0...",
|
|
192
|
+
"Accept-Language": "pt-BR,pt;q=0.9",
|
|
193
|
+
"Custom-Header": "value"
|
|
194
|
+
}
|
|
195
|
+
)
|
|
196
|
+
)
|
|
197
|
+
|
|
198
|
+
# Ou por requisição
|
|
199
|
+
response = client.get(
|
|
200
|
+
"https://example.com",
|
|
201
|
+
headers={"Authorization": "Bearer token"}
|
|
202
|
+
)
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### Cookies
|
|
206
|
+
|
|
207
|
+
```python
|
|
208
|
+
# Obter todos os cookies
|
|
209
|
+
cookies = client.get_cookies()
|
|
210
|
+
|
|
211
|
+
# Obter cookie específico
|
|
212
|
+
value = client.get_cookie_by_name("session_id")
|
|
213
|
+
|
|
214
|
+
# Definir cookie
|
|
215
|
+
client.set_cookie("name", "value")
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
## 🔒 Thread Safety
|
|
219
|
+
|
|
220
|
+
A biblioteca é thread-safe e pode ser usada em ambientes multi-threaded:
|
|
221
|
+
|
|
222
|
+
```python
|
|
223
|
+
import concurrent.futures
|
|
224
|
+
|
|
225
|
+
client = NotifyTLSClient(ClientConfiguration.aggressive(proxies))
|
|
226
|
+
|
|
227
|
+
def make_request(url):
|
|
228
|
+
return client.get(url)
|
|
229
|
+
|
|
230
|
+
with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
|
|
231
|
+
urls = ["https://example.com"] * 100
|
|
232
|
+
results = list(executor.map(make_request, urls))
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
## 📊 Logging
|
|
236
|
+
|
|
237
|
+
```python
|
|
238
|
+
import logging
|
|
239
|
+
|
|
240
|
+
# Habilitar logs de debug
|
|
241
|
+
logging.basicConfig(level=logging.DEBUG)
|
|
242
|
+
|
|
243
|
+
# Ou configurar apenas para notify_tls_client
|
|
244
|
+
logger = logging.getLogger("notify_tls_client")
|
|
245
|
+
logger.setLevel(logging.DEBUG)
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
## 🛠️ Métodos HTTP Suportados
|
|
249
|
+
|
|
250
|
+
```python
|
|
251
|
+
# GET
|
|
252
|
+
response = client.get(url, params={"key": "value"})
|
|
253
|
+
|
|
254
|
+
# POST
|
|
255
|
+
response = client.post(url, json={"data": "value"})
|
|
256
|
+
response = client.post(url, data="form data")
|
|
257
|
+
|
|
258
|
+
# PUT
|
|
259
|
+
response = client.put(url, json={"data": "value"})
|
|
260
|
+
|
|
261
|
+
# PATCH
|
|
262
|
+
response = client.patch(url, json={"data": "value"})
|
|
263
|
+
|
|
264
|
+
# DELETE
|
|
265
|
+
response = client.delete(url)
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
## 📖 Documentação Completa
|
|
269
|
+
|
|
270
|
+
Para documentação detalhada sobre arquitetura, componentes internos e exemplos avançados, consulte:
|
|
271
|
+
- [CLAUDE.md](CLAUDE.md) - Guia completo de desenvolvimento
|
|
272
|
+
- [examples/](examples/) - Exemplos de código
|
|
273
|
+
|
|
274
|
+
## 🤝 Contribuindo
|
|
275
|
+
|
|
276
|
+
Contribuições são bem-vindas! Por favor, leia [CONTRIBUTING.md](CONTRIBUTING.md) para detalhes sobre nosso código de conduta e processo de submissão de pull requests.
|
|
277
|
+
|
|
278
|
+
## 📝 Changelog
|
|
279
|
+
|
|
280
|
+
Veja [CHANGELOG.md](CHANGELOG.md) para histórico de versões e mudanças.
|
|
281
|
+
|
|
282
|
+
## 📄 Licença
|
|
283
|
+
|
|
284
|
+
Este projeto está licenciado sob a Licença MIT - veja o arquivo [LICENSE](LICENSE) para detalhes.
|
|
285
|
+
|
|
286
|
+
## ⚠️ Aviso Legal
|
|
287
|
+
|
|
288
|
+
Esta biblioteca é fornecida apenas para fins educacionais e de pesquisa. O uso desta ferramenta para violar termos de serviço de websites, realizar scraping não autorizado ou qualquer atividade ilegal é de sua responsabilidade. Os desenvolvedores não se responsabilizam pelo uso indevido desta biblioteca.
|
|
289
|
+
|
|
290
|
+
## 🙏 Agradecimentos
|
|
291
|
+
|
|
292
|
+
- [tls-client](https://github.com/bogdanfinn/tls-client) - Biblioteca Go subjacente para TLS fingerprinting
|
|
293
|
+
- Comunidade Python por ferramentas e bibliotecas incríveis
|
|
294
|
+
|
|
295
|
+
## 📞 Suporte
|
|
296
|
+
|
|
297
|
+
- **Issues**: [GitHub Issues](https://github.com/jefersonAlbara/notify-tls-client/issues)
|
|
298
|
+
- **Discussões**: [GitHub Discussions](https://github.com/jefersonAlbara/notify-tls-client/discussions)
|
|
299
|
+
|
|
300
|
+
---
|
|
301
|
+
|
|
302
|
+
**Desenvolvido com ❤️ para a comunidade Python**
|
{notify_tls_client-2.0.0 → notify_tls_client-2.0.1}/notify_tls_client/config/recovery_config.py
RENAMED
|
@@ -44,10 +44,15 @@ class RecoveryConfig:
|
|
|
44
44
|
instantiate_new_client_on_forbidden_response: bool = False
|
|
45
45
|
instantiate_new_client_on_exception: bool = False
|
|
46
46
|
change_client_identifier_on_forbidden_response: bool = False
|
|
47
|
-
status_codes_to_forbidden_response_handle:
|
|
47
|
+
status_codes_to_forbidden_response_handle: tuple[int, ...] = field(default_factory=lambda: (403,))
|
|
48
48
|
|
|
49
49
|
def __post_init__(self):
|
|
50
50
|
"""Valida os parâmetros de configuração."""
|
|
51
|
+
# Converter lista para tuple se necessário (compatibilidade)
|
|
52
|
+
if isinstance(self.status_codes_to_forbidden_response_handle, list):
|
|
53
|
+
object.__setattr__(self, 'status_codes_to_forbidden_response_handle',
|
|
54
|
+
tuple(self.status_codes_to_forbidden_response_handle))
|
|
55
|
+
|
|
51
56
|
if not self.status_codes_to_forbidden_response_handle:
|
|
52
57
|
raise ValueError("status_codes_to_forbidden_response_handle não pode ser vazio")
|
|
53
58
|
|