Looking for international version of our service? Go to 2captcha.com

Блог программ

Антидетект + автоматизация: инженерный разбор на примере MuLogin

Что если я скажу вам, что существуют инструменты, которые способны настолько упростить работу с веб автоматизацией, что вы сможете сократить время на разработку в разы? Уверен, вы слышали об этих инструментах - это антидетект браузеры. В данной статье на примере антидетект браузера MuLogin, изучим автоматизацию с использованием антиков.

Ключевая мысль, перед тем как погрузиться в тему глубже: антидетект-браузер вроде MuLogin не заменяет инженерную работу, а дает хороший "фундамент" - готовые отпечатки, профили и API. Стабильность автоматизации решают архитектура бота, очередь задач, паттерны поведения и грамотные метрики.

Что делает антидетект и чем полезен MuLogin

Современные антибот-системы опираются на три слоя:

  • Сеть: IP‑репутация, прокси, AS, мобильный/резидентский трафик.
  • Отпечаток браузера: User-Agent, WebGL, Canvas, шрифты, плагины, таймзона, разрешение экрана, медиадевайсы и сотни других сигналов.​
  • Поведение: скорость кликов и скролла, паттерны навигации, доля чтения vs действия, ошибки форм, CAPTCHAs, аномальные маршруты.

Обычный Selenium/Playwright:

  • дает идеально одинаковый фингерпринт;
  • оставляет явные маркеры автоматизации (navigator.webdriver, CDP‑следы и т.п.);​
  • чаще всего крутится на дешёвых серверных прокси.

Антидетект‑браузеры решают первый и второй слой:

  • создают изолированные профили с разными отпечатками, cookies, localStorage и т.д.;
  • подменяют браузерные API: Canvas, WebGL, WebRTC, медиадевайсы, SSL‑фингерпринт, геоданные, battery API, Bluetooth, SpeechSynthesis, headers и пр.;
  • интегрируются с резидентными (мобильными) прокси;​
  • предоставляют локальный и облачный API для автоматизации профилей.

Антидетект браузер MuLogin, в частности:

  • управляет сотнями и тысячами профилей с независимыми фингерпринтами и полной изоляцией окружения;​
  • предоставляет Local REST API на 127.0.0.1:30725 и облачный API https://a.mulogin.com для создания/запуска/остановки/шаринга профилей;
  • официально поддерживает интеграцию с Selenium и Puppeteer, Playwright подключается архитектурно теми же CDP‑механизмами;​
  • реализует прямую работу через Chrome DevTools Protocol (debuggerAddress), а не классический WebDriver-протокол.

Антидетект снимает большую часть "низкоуровневой боли". Всё, что касается сценариев, таймингов, очереди задач, - это уже задача разработчика.

Способы подключить антидетект к коду

Стандартная работа с антидетект браузером понятна - создаем профили (настраиваем отпечатки браузера, подключаем прокси, назначаем роли и работаем). Но это все про использование антика напрямую, давайте подойдем к вопросу чуть более технически.

Локальный браузер + WebDriver (Selenium через MuLogin)

Классическая схема с MuLogin + Selenium выглядит так:

  1. В MuLogin включается автоматизация браузера и задается порт (по умолчанию 30725).
  2. По Local API вызывается /api/v1/profile/start с profileId и флагами.
  3. В ответ приходит JSON со:
  • status (OK/ERROR),
  • value - строка с адресом вида ws://127.0.0.1:XXXXX/devtools/browser/... (используется как debuggerAddress),
  • chromedriver - полный путь к подходящему ChromeDriver.
  1. Selenium подключается к уже запущенному браузеру через debuggerAddress, а не стартует свой экземпляр.

Пример

language Copy
  from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service as ChromeService
import requests

mla_profile_id = 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'

# 1. Стартуем профиль через Local API MuLogin
mla_url = f'http://127.0.0.1:30725/api/v1/profile/start?skiplock=true&profileId={mla_profile_id}'
resp = requests.get(mla_url)
data = resp.json()

if data['status'] == 'ERROR':
    print(data['value'])  # текст ошибки от MuLogin
    quit()

print(data['value'])  # строка с адресом DevTools/remote debugging

# 2. Подключаемся к уже запущенному профилю
chrome_options = Options()
chrome_options.add_experimental_option("debuggerAddress", data['value'][7:])  
# срез [7:] убирает "ws://", оставляя host:port

service = ChromeService(executable_path=data['chromedriver'])

driver = webdriver.Chrome(service=service, options=chrome_options)

driver.get('https://www.bing.com/')
print(driver.command_executor._url)
print(driver.session_id)
print('ok it is done')
# driver.quit()  # закрывать лучше через MuLogin API /profile/stop

Ключевые моменты:

  • MuLogin сам стартует браузерный профиль и отдаёт путь к совместимому chromedriver, что снимает проблему несовпадения версий.
  • Со стороны Selenium используется режим подключения к рантайму через DevTools (debuggerAddress), а не WebDriver‑хендшейк.
  • Через Local API можно задать/переопределить прокси для конкретного запуска (proxytype, proxyserver, proxyport, логин/пароль), при этом базовые настройки профиля не меняются - только текущая сессия.

Плюсы:

  • простой вход для тех, кто уже плотно сидит на Selenium;
  • официальный пример от MuLogin;
  • легко масштабируется через несколько воркеров, каждый из которых стартует/стопит нужные profileId.

Минусы:

  • Selenium по умолчанию сильно палится, антидетект сглаживает часть маркеров, но поведение и высокоуровневые паттерны остаются.

HTTP API: open_profile / newtab / execute / screenshot

MuLogin даёт довольно богатый Local API для управления профилем без прямого подключения WebDriver:

Endpoint - Назначение - Метод

/api/v1/profile/start - Запуск профиля (c optional proxy/automation) - GET
/api/v1/profile/stop - Остановка профиля - GET
/api/v1/profile/newtab - Открытие новой вкладки с URL - GET
/api/v1/profile/source - Получение HTML‑кода активной вкладки - GET
/api/v1/profile/refresh - Обновление страницы - GET
/api/v1/profile/ScreenShot - Скриншот страницы - POST
/api/v1/profile/execute (Execute Script) - Выполнить JavaScript в контексте вкладки - POST

Открыть новую вкладку:

language Copy
http://127.0.0.1:30725/api/v1/profile/newtab?profileId=...&url=https://example.com

Обновить страницу:

language Copy
http://127.0.0.1:30725/api/v1/profile/refresh?profileId=...

Получить HTML‑код:

language Copy
http://127.0.0.1:30725/api/v1/profile/source?profileId=...

Простейший пример "HTTP‑бота" без Selenium:

language Copy
import requests
import time

BASE = "http://127.0.0.1:30725/api/v1"
PROFILE_ID = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"

def start_profile():
    r = requests.get(f"{BASE}/profile/start", params={
        "skiplock": "true",
        "profileId": PROFILE_ID
    })
    data = r.json()
    if data["status"] == "ERROR":
        raise RuntimeError(data["value"])
    return data

def open_tab(url):
    requests.get(f"{BASE}/profile/newtab", params={
        "profileId": PROFILE_ID,
        "url": url
    })

def get_source():
    r = requests.get(f"{BASE}/profile/source", params={
        "profileId": PROFILE_ID
    })
    return r.text

start_profile()
open_tab("https://example.com")
time.sleep(5)
html = get_source()
print(len(html))

Плюсы такого подхода:

  • минимальный стек: достаточно requests (HTTP‑клиента);
  • легко интегрируется в уже существующие системы (например, когда автотесты запускаются не из кода, а из внешнего оркестратора);
  • удобно для массовых, простых задач: проверка лендингов, мониторинг цен, базовый краулинг.

Минусы:

  • без WebDriver (Playwright или Puppeteer) нелегко реализовать сложное взаимодействие с DOM (drag&drop, rich UI, SPA‑логика);
  • менее удобная отладка сценариев.

Remote debugging (CDP) и управление через DevTools

Практически все современные антидетект‑браузеры строят автоматизацию вокруг DevTools Protocol (CDP):

  • Chrome/Chromium предоставляет WebSocket‑эндпоинт вида ws://host:port/devtools/browser/...;
  • Puppeteer и Playwright умеют подключаться к уже запущенному браузеру через этот эндпоинт;
  • антидетект браузер стартуют профиль и в ответ на API дают готовый wsEndpoint.

У MuLogin это выглядит так:

  1. /api/v1/profile/start?... → JSON со строкой value = "ws://127.0.0.1:XXXXX/devtools/browser/...";
  2. Для Selenium эту строку режут и используют в debuggerAddress.
  3. Для Puppeteer (Playwright) её можно использовать напрямую как wsEndpoint для connect (connectOverCDP) (архитектурный паттерн, широко применяемый в других антидетектах).

Пример общего подхода с Puppeteer (Node.js):

language Copy
import puppeteer from 'puppeteer-core';
import fetch from 'node-fetch';

// 1. Получаем wsEndpoint от антидетекта
const res = await fetch('http://127.0.0.1:30725/api/v1/profile/start?skiplock=true&profileId=...');
const data = await res.json();
if (data.status === 'ERROR') {
  throw new Error(data.value);
}
const wsEndpoint = data.value; // ws://127.0.0.1:XXXXX/devtools/browser/...

// 2. Подключаемся к уже запущенному браузеру
const browser = await puppeteer.connect({ browserWSEndpoint: wsEndpoint });
const [page] = await browser.pages();
await page.goto('https://bot.sannysoft.com/');
await page.waitForTimeout(5000);
await page.screenshot({ path: 'check.png', fullPage: true });

Аналогично работает Playwright:

language Copy
import { chromium } from 'playwright';

const wsEndpoint = process.env.CDP_ENDPOINT!; // сюда кладётся значение из /profile/start

const browser = await chromium.connectOverCDP(wsEndpoint);
const context = browser.contexts()[0] ?? await browser.newContext();
const page = await context.newPage();

await page.goto('https://example.com');

Подход через CDP:

  • снимает часть Selenium‑специфичных следов (WebDriver протокол, webdriver‑capabilities);
  • даёт тот же уровень контроля, что и локальный chromium.launch() (puppeteer.launch());
  • широко используется в антидетект‑экосистеме (Multilogin + Playwright, другие решения).

Архитектура автотестов (ботов) поверх антидетекта

Теперь рассмотрим вопрос реализации многопоточности, ведь не секрет, что антики в основном для этого и придумывали, чтобы реализовывать мультиаккаунтинг. Вот как это работает.

Один процесс = один профиль vs пул воркеров

Есть два базовых подхода:

Подход - Плюсы - Минусы

1 процесс = 1 профиль - Простота, изоляция, удобная отладка - Память/CPU растут линейно, сложно управлять большим парком
Пул воркеров + подключения к профилям - Гибкая утилизация ресурсов, легко масштабировать по задачам - Сложность очереди и синхронизации профилей

Для MuLogin архитектура обычно выглядит так:

  • MuLogin‑daemon (GUI или headless) крутится на сервере/станции;
  • приложение (бот) общается с ним по Local API (127.0.0.1:30725) и/или облачному API a.mulogin.com;
  • каждый воркер:
    • берёт задачу из очереди;
    • стартует нужный profileId (если не запущен);
    • подключается через Selenium / CDP;
    • выполняет сценарий;
    • логирует метрики;
    • при необходимости останавливает профиль.

Очередь задач и диспетчер профилей

Рабочая схема - централизованная очередь, где профиль и аккаунт - отдельные сущности:

Поле - Что хранится

task_id - уникальный ID задачи
profile_id - связанный MuLogin‑профиль
account_id - ID бизнес‑аккаунта (FB, Amazon, Ads и т.п.)
priority - приоритет обработки
status - pending / running / done / failed / blocked
next_run_at - когда можно брать задачу (rate limit / паузы)
last_error - код ошибки / тип блокировки / причина остановки
ttl_score - нежесткий TTL‑индикатор профиля

Поверх этого строится диспетчер:

  • ограничение N профилей домена на IP;
  • лимит одновременных задач на один профиль (max_sessions_per_profile = 1 почти всегда для боевой реализации);
  • прогрев профилей (первые сессии - только чтение, без критичных действий).

Почему "голый" Selenium палится

Почему нельзя просто использовать Selenium без наворотов в виде антидетект браузера? Можно, но с антидетект браузером будет более эффективно. А в чем проблема голого Selenium ниже.

navigator.webdriver и WebDriver‑протокол

Базовый ChromeDriver:

  • устанавливает navigator.webdriver = true, что по спецификации означает "браузер под управлением WebDriver";
  • добавляет флаги в командную строку (--enable-automation, --disable-infobars) и расширение автотестов;
  • формирует специфичные HTTP‑заголовки и поведение сетевого стека.

Детект строится очень просто:

language Copy
if (navigator.webdriver) isBot = true;

Расширенные техники включают:

  • проверку наличия chrome.webstore, window.chrome и других объектов;
  • анализ стека ошибок и поведения console.log (существуют даже отдельные CDP‑детекторы);
  • проверку headless‑режима через userAgent, Canvas и поведение рендеринга.

Конечно, можно использовать подобные варианты, чтобы замести следы:

  • --disable-blink-features=AutomationControlled;
  • excludeSwitches: ["enable-automation"];
  • useAutomationExtension: False;
  • вставка скрипта через Page.addScriptToEvaluateOnNewDocument для переопределения navigator.webdriver.

Но даже авторы подобных решений предупреждают: любое ручное ковыряние может ломать навигацию или оставлять нелинейные следы. Да и предусмотреть все не всегда получается.

Headless и поведенческие маркеры

С headless режимом тоже есть свои сложности:

  • Headless‑режим с дефолтным окном, отличающимся от массовых реальных пользователей:
    • аномально быстрые клики, отсутствие естественных скроллов;
    • линейные переходы по урлам без "шума" (нет переходов назад, нет ошибок ввода, нет движений мыши и т.д.);
    • отсутствие разнообразия фингерпринтов (один и тот же Canvas/WebGL/шрифты и пр.).

Что патчит антидетект и что остаётся в коде

Что берёт на себя MuLogin

Современные антидетект‑браузеры, в том числе и MuLogin, целятся именно в фингерпринт и интеграцию с автоматизацией:

  • уникальные фингерпринты на каждый профиль, с обновляемой базой параметров;
  • гибкую настройку фингерпринта: медиадевайсы, SSL, Bluetooth API, battery API, SpeechSynthesis, заголовки и многое другое;
  • изоляцию профилей и шифрование локальных данных профиля;
  • интеграцию с прокси‑сетями (в том числе 2prx.com.);​
  • Local REST API и облачный API для управления профилями и автоматизации;
  • поддерживаемую интеграцию с Selenium и Puppeteer для выполнения end‑to‑end тестов и сложных сценариев.

Что нужно доделывать в коде

Даже при идеальном фингерпринте остаются поведенческие и оркестрационные аспекты:

  1. Тайминги: случайные, но правдоподобные паузы, зависящие от сложности действия.
  2. Клики и мышь:
  • движения мыши с траекториями, а не телепорт;
  • редкие "промахи" и корректировки.
  1. Скроллы:
  • инерционный скролл, остановки в середине страницы;
  • переходы к якорям, использование колесика мыши.
  1. Навигация:
  • не только прямые переходы goto, но и клики по меню, кнопкам;
  • иногда возврат назад, ошибки ввода, повторная отправка формы.
  1. Сетевая дисциплина:
  • ограничения по RPS на домен/профиль/IP;
  • паузы между сессиями и "ночной" режим профилей.
  1. CAPTCHA‑поведение:
  • не мгновенное и не 100%‑успешное решение;
  • иногда ручное подтверждение/ошибки.

MuLogin добавляет полезную опцию

--disable-blink-features=AutomationControlled на уровне настроек профиля, что является дополнительной мерой "антидетекта". Но без адекватных сценариев и таймингов этот флаг мало что решит.​

Метрики автоматики: как понять, что вас "чуют"

Как правило, большинство разработчиков и вайб-кодеров используют следующие метрики "работает/не работает". Но это все же несколько примитивно, ведь можно подойти к вопросу творчески и ввести более явные метрики, чтобы понимать в чем именно загвоздка, в том числе.

Detection rate

Detection rate в прикладном смысле - доля сессий/действий, где сайт явно включает защиту:

  • возвращает challenge‑страницу (JS‑челлендж, "проверка браузера", reCAPTCHA на весь экран);
  • выдаёт специфичный HTTP‑код (429, 403 с текстом про бота, специальные anti‑bot responses);
  • подсовывает страницу‑заглушку вместо целевого контента.

Формула достаточно проста:

language Copy
Detection Rate = detected_events / total_sessions или total_actions

Примеры источников данных:

  • собственные логи HTTP‑код (URL, тайтл, ключевые фразы в HTML);
  • внешние сервисы;
  • тест‑страницы вроде известных бот‑чеков (bot.sannysoft, nowsecure и пр.).

Средний TTL профиля до первого подозрения

Здесь TTL - время жизни профиля в более‑менее комфортном режиме до серьёзных осложнений:

  • резкое увеличение частоты появления капчи;
  • постоянные JS‑челленджи;
  • частые 403/429 на базовых страницах;
  • необходимость подтверждать логин по SMS/почте на каждом заходе.

Практически:

  • фиксируется first_seen_at для профиля (или для конкретного домена в этом профиле);
  • логируются все события "подозрения";
  • TTL = time_of_first_serious_issue - first_seen_at.

Полезно хранить TTL по домену и профилю, а не только в целом.

Количество капчи на 1000 действий

Количество капчи на 1000 действий - отличный "индикатор запаха":

language Copy
CAPTCHA per 1000 actions = (captcha_events / total_actions) × 1000

Где:

  • captcha_events - число срабатываний CAPTCHA‑виджетов (по URL, DOM‑селектору или API‑ответу от solver’a);
  • total_actions - клики, сабмиты форм, значимые переходы.

Реалистичный сценарий:

  • для обычного пользователя CAPTCHA появляется крайне редко;
  • если бот начал видеть их каждые 20-30 действий, значит профиль/поведение/прокси вызывают подозрение.

Пример агрегации (псевдо‑SQL):

language Copy
SELECT
  profile_id,
  domain,
  COUNT(*) FILTER (WHERE event_type = 'captcha') * 1000.0 /
  NULLIF(COUNT(*) FILTER (WHERE event_type IN ('click', 'submit', 'navigate')), 0)
    AS captchas_per_1000_actions
FROM events
GROUP BY profile_id, domain;

Практические советы из реального мира антидетекта - на что обращать внимание

  1. Следить за версией ядра и драйвера
    MuLogin явно указывает, что chromedriver должен соответствовать версии ядра, и даже даёт прямые ссылки на подходящие билды. Несоответствие = странные ошибки/падения, которые легко перепутать с антиботом.
  2. Избегать headless там, где это возможно
    В headless‑режиме даже без автоматизации, по данным открытых гайдов, множество тестов на бот‑страницах (вроде bot.sannysoft) проваливаются - Canvas, WebGL, плагины и т.п. Антидетект может маскировать часть из них, но headful + антидетект + разумные тайминги почти всегда стабильнее.
  3. Check‑страницы как интеграционный тест
    Набор тестовых страниц:
  • бот‑чек на фингерпринты (Canvas, WebGL, navigator.webdriver и др.);
  • Cloudflare/anti‑bot тесты.
  1. Полезно прогонять по ним каждый новый билд сценариев и каждую крупную смену настроек MuLogin.
  2. Разделять профили по задачам
    Профили, которые:
  • только читают страницы,
  • активно создают/меняют аккаунты,
  • работают с деньгами/рекламой,
  • лучше не смешивать. Метрики TTL и CAPTCHA будут сильно отличаться.
  1. Использовать облачный API для управления профилями
    Облачный API MuLogin (a.mulogin.com/v1/profile/...) позволяет массово:
  • листать профили;
  • удалять/передавать владение;
  • шарить профили между аккаунтами;
    Это удобно для CI/CD и мультикомандной работы.

Вместо вывода

Антидетект‑браузер MuLogin:

  • закрывает техническую часть фингерпринта и изоляции профилей;
  • даёт удобные API для автоматизации через Selenium/DevTools/HTTP;​
  • упрощает работу с прокси и командой.

Но устойчивость сценариев определяют:

  • архитектура (воркеры, очередь задач, политика профилей);
  • поведенческие паттерны (тайминги, клики, скроллы, ошибки);
  • метрики (Detection Rate, TTL, CAPTCHA per 1000 actions).

Если всё это учесть, то связка "MuLogin + Selenium/Playwright/Puppeteer" позволяет строить достаточно надежные, масштабируемые боты и автотесты, которые живут долго и предсказуемо, а не только "проходят один тест на bot.sannysoft.com" и тут же дохнут на реальном проекте.