You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
|`__dyn`| Dynamic modules hash |`"__dyn":"..."` (no longer reliably present in HTML; fallback values used) |
96
+
|`__csr`| CSR hash |`"__csr":"..."` (no longer reliably present in HTML; fallback values used) |
97
+
|`v`| Version parameter |`"v":"fbece7"` (dynamically extracted when available) |
98
+
|`x-asbd-id`| ASBD identifier |`"asbd_id":"359341"` (dynamically extracted when available) |
97
99
|`jazoest`| Anti-abuse token |`"jazoest":12345` or computed from LSD |
98
100
99
101
Fallback values from `constants.py` are used when extraction fails.
@@ -170,9 +172,9 @@ Sessions become stale after `MAX_SESSION_AGE` (30 minutes by default). Before ea
170
172
171
173
`_refresh_session()` performs a full re-initialization:
172
174
173
-
1. Close the old `requests.Session`
175
+
1. Close the old session (`requests.Session` or `curl_cffi.requests.Session`)
174
176
2. Generate a new `BrowserFingerprint`
175
-
3. Create a fresh session with new headers
177
+
3. Create a fresh session with new headers (preferring `curl_cffi` when available)
176
178
4. Re-run `initialize()` to get new tokens
177
179
5. Track consecutive refresh failures to prevent infinite loops
178
180
@@ -192,14 +194,18 @@ If `max_refresh_attempts` consecutive refreshes fail, `SessionExpiredError` is r
192
194
193
195
`fingerprint.py` generates randomized but internally-consistent browser identities. Each session gets a unique combination of:
194
196
195
-
-**Chrome version**: Randomly selected from 8 recent versions (125--132)
197
+
-**Chrome version**: Randomly selected from 6 recent versions (140--145)
196
198
-**Platform**: Windows or macOS with matching User-Agent OS string and `sec-ch-ua-platform`
197
199
-**Viewport**: 8 common screen resolutions
198
200
-**DPR**: 5 device pixel ratio values
199
201
-**"Not A Brand" hint**: 4 variations matching real Chrome behavior
200
202
201
203
All headers derived from the fingerprint are self-consistent -- the Chrome version in the User-Agent matches `sec-ch-ua`, the platform in the UA matches `sec-ch-ua-platform`, etc.
202
204
205
+
### TLS Fingerprint Impersonation
206
+
207
+
When the optional `curl_cffi` dependency is installed (`pip install meta-ads-collector[stealth]`), the client uses `curl_cffi.requests.Session(impersonate="chrome")` instead of `requests.Session`. This provides Chrome-like TLS fingerprints (JA3/JA4) at the connection level, making requests indistinguishable from a real Chrome browser to TLS-based bot detection systems. If `curl_cffi` is not installed, the library falls back to `requests.Session` transparently.
208
+
203
209
### Request Mimicry
204
210
205
211
The client replicates the exact request patterns of a real browser:
0 commit comments