use browser_oxide::Page;
async fn fetch_and_classify(url: &str) -> String {
let profile = browser_oxide::stealth::presets::chrome_148_macos();
let mut page = match Page::navigate(url, profile, 3).await {
Ok(p) => p,
Err(e) => return format!("ERROR: {e}"),
};
let html = page.content();
let lower = html.to_lowercase();
let len = html.len();
let strong_markers: &[(&str, &str)] = &[
("just a moment", "ManagedChallenge-CHL"),
("checking your browser", "ManagedChallenge-CHL"),
("cf-browser-verification", "ManagedChallenge-CHL"),
("_kpsdk", "ScriptChallenge-CHL"),
("ips.js", "ScriptChallenge-CHL"),
("/_sec/cp_challenge", "SecCpt-CHL"),
("akam/13", "SensorChallenge-CHL"),
("_abck", "SensorChallenge-CHL"),
("captcha-delivery", "Interstitial-CHL"),
("ddcaptchaencoded", "Interstitial-CHL"),
("press & hold", "HoldChallenge-PaH"),
("_pxhd", "BehaviorChallenge-CHL"),
];
let weak_markers: &[(&str, &str)] = &[
("captcha", "captcha-CHL"),
("403 forbidden", "BLOCKED"),
("access denied", "BLOCKED"),
("blocked", "BLOCKED"),
];
for (needle, tag) in strong_markers {
if lower.contains(needle) {
return format!("{tag} (body len={len})");
}
}
if len < 100 * 1024 {
for (needle, tag) in weak_markers {
if lower.contains(needle) {
return format!("{tag} (body len={len})");
}
}
}
if len < 1000 {
return format!("THIN-BODY (len={len})");
}
format!("L3-RENDERED (len={len})")
}
#[tokio::test]
#[ignore]
async fn chl_canadagoose() {
let r = fetch_and_classify("https://www.canadagoose.com/").await;
eprintln!("canadagoose: {r}");
}
#[tokio::test]
#[ignore]
async fn chl_hyatt() {
let r = fetch_and_classify("https://www.hyatt.com/").await;
eprintln!("hyatt: {r}");
}
#[tokio::test]
#[ignore]
async fn chl_retailer_marker() {
let r = fetch_and_classify("https://www.adidas.com/us").await;
eprintln!("adidas: {r}");
}
#[tokio::test]
#[ignore]
async fn chl_zillow() {
let r = fetch_and_classify("https://www.zillow.com/").await;
eprintln!("zillow: {r}");
}
#[tokio::test]
#[ignore]
async fn chl_wildberries() {
let r = fetch_and_classify("https://www.wildberries.ru/").await;
eprintln!("wildberries: {r}");
}
#[tokio::test]
#[ignore]
async fn chl_ozon() {
let r = fetch_and_classify("https://www.ozon.ru/").await;
eprintln!("ozon: {r}");
}
#[tokio::test]
#[ignore]
async fn chl_douyin() {
let r = fetch_and_classify("https://www.douyin.com/").await;
eprintln!("douyin: {r}");
}
#[tokio::test]
#[ignore]
async fn fp_creepjs() {
let r = fetch_and_classify("https://abrahamjuliot.github.io/creepjs/").await;
eprintln!("creepjs: {r}");
}
#[tokio::test]
#[ignore]
async fn fp_sannysoft() {
let r = fetch_and_classify("https://bot.sannysoft.com/").await;
eprintln!("sannysoft: {r}");
}
#[tokio::test]
#[ignore]
async fn fp_browserleaks_canvas() {
let r = fetch_and_classify("https://browserleaks.com/canvas").await;
eprintln!("browserleaks-canvas: {r}");
}
#[tokio::test]
#[ignore]
async fn fp_pixelscan() {
let r = fetch_and_classify("https://pixelscan.net/").await;
eprintln!("pixelscan: {r}");
}
#[tokio::test]
#[ignore]
async fn fp_areyouheadless() {
let r = fetch_and_classify("https://arh.antoinevastel.com/bots/areyouheadless").await;
eprintln!("areyouheadless: {r}");
}
#[tokio::test]
#[ignore]
async fn fp_botd() {
let r = fetch_and_classify("https://fingerprint.com/products/bot-detection/").await;
eprintln!("botd: {r}");
}
#[tokio::test]
#[ignore]
async fn fp_fingerprintscan() {
let r = fetch_and_classify("https://fingerprintscan.com/").await;
eprintln!("fingerprintscan: {r}");
}
#[tokio::test]
#[ignore]
async fn fp_managed_challenge_page() {
let r = fetch_and_classify("https://www.nowsecure.nl/").await;
eprintln!("nowsecure: {r}");
}