Антидетект + автоматизация: инженерный разбор на примере 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и облачный APIhttps://a.mulogin.comдля создания/запуска/остановки/шаринга профилей; - официально поддерживает интеграцию с Selenium и Puppeteer, Playwright подключается архитектурно теми же CDP‑механизмами;
- реализует прямую работу через Chrome DevTools Protocol (debuggerAddress), а не классический WebDriver-протокол.

Антидетект снимает большую часть "низкоуровневой боли". Всё, что касается сценариев, таймингов, очереди задач, - это уже задача разработчика.
Способы подключить антидетект к коду
Стандартная работа с антидетект браузером понятна - создаем профили (настраиваем отпечатки браузера, подключаем прокси, назначаем роли и работаем). Но это все про использование антика напрямую, давайте подойдем к вопросу чуть более технически.
Локальный браузер + WebDriver (Selenium через MuLogin)
Классическая схема с MuLogin + Selenium выглядит так:

- В MuLogin включается автоматизация браузера и задается порт (по умолчанию
30725). - По Local API вызывается
/api/v1/profile/start с profileIdи флагами. - В ответ приходит JSON со:
status (OK/ERROR),value- строка с адресом видаws://127.0.0.1:XXXXX/devtools/browser/...(используется какdebuggerAddress),chromedriver- полный путь к подходящему ChromeDriver.
- Selenium подключается к уже запущенному браузеру через
debuggerAddress, а не стартует свой экземпляр.
Пример
language
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
http://127.0.0.1:30725/api/v1/profile/newtab?profileId=...&url=https://example.com
Обновить страницу:
language
http://127.0.0.1:30725/api/v1/profile/refresh?profileId=...
Получить HTML‑код:
language
http://127.0.0.1:30725/api/v1/profile/source?profileId=...

Простейший пример "HTTP‑бота" без Selenium:
language
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 это выглядит так:
/api/v1/profile/start?...→ JSON со строкойvalue = "ws://127.0.0.1:XXXXX/devtools/browser/...";- Для Selenium эту строку режут и используют в
debuggerAddress. - Для Puppeteer (Playwright) её можно использовать напрямую как
wsEndpointдляconnect(connectOverCDP) (архитектурный паттерн, широко применяемый в других антидетектах).
Пример общего подхода с Puppeteer (Node.js):
language
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
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) и/или облачному APIa.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
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 тестов и сложных сценариев.
Что нужно доделывать в коде
Даже при идеальном фингерпринте остаются поведенческие и оркестрационные аспекты:
- Тайминги: случайные, но правдоподобные паузы, зависящие от сложности действия.
- Клики и мышь:
- движения мыши с траекториями, а не телепорт;
- редкие "промахи" и корректировки.
- Скроллы:
- инерционный скролл, остановки в середине страницы;
- переходы к якорям, использование колесика мыши.
- Навигация:
- не только прямые переходы
goto, но и клики по меню, кнопкам; - иногда возврат назад, ошибки ввода, повторная отправка формы.
- Сетевая дисциплина:
- ограничения по RPS на домен/профиль/IP;
- паузы между сессиями и "ночной" режим профилей.
- CAPTCHA‑поведение:
- не мгновенное и не 100%‑успешное решение;
- иногда ручное подтверждение/ошибки.
MuLogin добавляет полезную опцию
--disable-blink-features=AutomationControlled на уровне настроек профиля, что является дополнительной мерой "антидетекта". Но без адекватных сценариев и таймингов этот флаг мало что решит.
Метрики автоматики: как понять, что вас "чуют"
Как правило, большинство разработчиков и вайб-кодеров используют следующие метрики "работает/не работает". Но это все же несколько примитивно, ведь можно подойти к вопросу творчески и ввести более явные метрики, чтобы понимать в чем именно загвоздка, в том числе.
Detection rate
Detection rate в прикладном смысле - доля сессий/действий, где сайт явно включает защиту:
- возвращает challenge‑страницу (JS‑челлендж, "проверка браузера", reCAPTCHA на весь экран);
- выдаёт специфичный HTTP‑код (429, 403 с текстом про бота, специальные anti‑bot responses);
- подсовывает страницу‑заглушку вместо целевого контента.
Формула достаточно проста:
language
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
CAPTCHA per 1000 actions = (captcha_events / total_actions) × 1000
Где:
captcha_events- число срабатываний CAPTCHA‑виджетов (по URL, DOM‑селектору или API‑ответу от solver’a);total_actions - клики, сабмиты форм, значимые переходы.
Реалистичный сценарий:
- для обычного пользователя CAPTCHA появляется крайне редко;
- если бот начал видеть их каждые 20-30 действий, значит профиль/поведение/прокси вызывают подозрение.
Пример агрегации (псевдо‑SQL):
language
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;

Практические советы из реального мира антидетекта - на что обращать внимание
- Следить за версией ядра и драйвера
MuLogin явно указывает, чтоchromedriverдолжен соответствовать версии ядра, и даже даёт прямые ссылки на подходящие билды. Несоответствие = странные ошибки/падения, которые легко перепутать с антиботом. - Избегать headless там, где это возможно
В headless‑режиме даже без автоматизации, по данным открытых гайдов, множество тестов на бот‑страницах (вроде bot.sannysoft) проваливаются - Canvas, WebGL, плагины и т.п. Антидетект может маскировать часть из них, но headful + антидетект + разумные тайминги почти всегда стабильнее. - Check‑страницы как интеграционный тест
Набор тестовых страниц:
- бот‑чек на фингерпринты (Canvas, WebGL, navigator.webdriver и др.);
- Cloudflare/anti‑bot тесты.
- Полезно прогонять по ним каждый новый билд сценариев и каждую крупную смену настроек MuLogin.
- Разделять профили по задачам
Профили, которые:
- только читают страницы,
- активно создают/меняют аккаунты,
- работают с деньгами/рекламой,
- лучше не смешивать. Метрики TTL и CAPTCHA будут сильно отличаться.
- Использовать облачный 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" и тут же дохнут на реальном проекте.