webclaw/crates/webclaw-fetch/src/browser.rs
Valerio b77767814a Bump to 0.5.4: SafariIos profile + Chrome fingerprint alignment + locale helper
- New BrowserProfile::SafariIos mapped to BrowserVariant::SafariIos26.
  Built on wreq_util::Emulation::SafariIos26 with 4 overrides (TLS
  extension order, HTTP/2 HEADERS priority, real Safari iOS 26 headers,
  gzip/deflate/br). Matches bogdanfinn safari_ios_26_0 JA3
  8d909525bd5bbb79f133d11cc05159fe exactly. Empirically 9/10 on
  immobiliare.it with country-it residential.

- BrowserProfile::Chrome aligned to bogdanfinn chrome_133: dropped
  MAX_CONCURRENT_STREAMS from H2 SETTINGS, priority weight 256,
  explicit extension_permutation, advertise h3 in ALPN and ALPS.
  JA3 43067709b025da334de1279a120f8e14, akamai_fp
  52d84b11737d980aef856699f885ca86. Fixes indeed.com and other
  Cloudflare-fronted sites.

- New locale module: accept_language_for_url / accept_language_for_tld.
  TLD to Accept-Language mapping, unknown TLDs default to en-US.
  DataDome geo-vs-locale cross-checks are now trivially satisfiable.

- wreq-util bumped 2.2.6 to 3.0.0-rc.10 for Emulation::SafariIos26.
2026-04-23 12:58:24 +02:00

56 lines
1.4 KiB
Rust

//! Browser fingerprint selection and rotation.
//! Maps our BrowserProfile enum to webclaw-http client builder methods.
/// Which browser identity to present at the TLS/HTTP layer.
#[derive(Debug, Clone, Default)]
pub enum BrowserProfile {
#[default]
Chrome,
Firefox,
/// Safari iOS 26 (iPhone). The one profile proven to defeat
/// DataDome's immobiliare.it / idealista.it / target.com-class
/// rules when paired with a country-scoped residential proxy.
SafariIos,
/// Randomly pick from all available profiles on each request.
Random,
}
/// A browser variant for building webclaw-http clients.
#[derive(Debug, Clone, Copy)]
pub enum BrowserVariant {
Chrome,
ChromeMacos,
Firefox,
Safari,
SafariIos26,
Edge,
}
/// All Chrome variants we ship.
pub fn chrome_variants() -> Vec<BrowserVariant> {
vec![BrowserVariant::Chrome, BrowserVariant::ChromeMacos]
}
/// All Firefox variants we ship.
pub fn firefox_variants() -> Vec<BrowserVariant> {
vec![BrowserVariant::Firefox]
}
/// All variants for maximum diversity in Random mode.
pub fn all_variants() -> Vec<BrowserVariant> {
vec![
BrowserVariant::Chrome,
BrowserVariant::ChromeMacos,
BrowserVariant::Firefox,
BrowserVariant::Safari,
BrowserVariant::Edge,
]
}
pub fn latest_chrome() -> BrowserVariant {
BrowserVariant::Chrome
}
pub fn latest_firefox() -> BrowserVariant {
BrowserVariant::Firefox
}