TL;DR: browser-use запускает Playwright с Chrome в headless-режиме. WhatsApp обнаруживает headless-сессии и блокирует аккаунт. После 12 блокировок и 47 сломанных сессий за 30 дней я заменил всю систему одним 10-строчным REST-вызовом к Whapi.Cloud. Просто уберите слой браузера. Нормальное API-соединение берёт на себя аутентификацию, переподключение и подтверждение доставки — без тех накладных расходов на обслуживание, которые создаёт браузерная автоматизация.
День, когда я нашёл репозиторий browser-use на GitHub
Репозиторий browser-use выглядел как готовый ярлык: направить LLM на браузер, открыть WhatsApp Web и отправлять сообщения. Никакого процесса одобрения API, никакой ежемесячной подписки. Моё тестовое сообщение дошло меньше чем за 30 секунд.
Я строил бот уведомлений для побочного e-commerce-проекта: подтверждения заказов и оповещения об отправке для клиентов, давших согласие при оформлении покупки. Официальная платформа WhatsApp Business требовала верификации бизнеса через Meta — это занимает время. Управляемые API-провайдеры вроде Whapi.Cloud подключаются через сокеты веб-сессии WhatsApp без очереди верификации, и настройка занимает меньше десяти минут. Тогда я этого ещё не знал. Я нашёл browser-use три дня назад, когда искал примеры автоматизации на GitHub, и кто-то в issues упоминал, что запускал его на WhatsApp Web.
Первый локальный тест прошёл безупречно. LLM-агент открыл WhatsApp Web, нашёл чат, набрал сообщение и отправил. Я написал обёртку, задеплоил на дроплет DigitalOcean за $10 в месяц и почувствовал себя достаточно умным, что обошёл подписку. Это длилось четыре дня.
На пятый день пайплайн перестал доставлять сообщения. Никаких исключений в логах. Браузер запускался, агент работал, но ничего не отправлялось. Я подключился к VPS по SSH и обнаружил, что WhatsApp Web показывает QR-код. Сессия истекла, пока процесс работал в headless-режиме. Я отсканировал с телефона, сообщения пошли ещё один день, потом сессия снова истекла.
QR-код истекал каждые 24–48 часов, а сессия умирала без каких-либо уведомлений. Мой «автоматизированный» пайплайн требовал рядом человека с телефоном в любой момент.
Я перелопатил issues browser-use на GitHub. Десятки тредов о сохранении сессий. Люди советовали сохранять контекст браузера на диск, запускать не в headless-режиме для первоначального сканирования, сохранять состояние localStorage в файл. Я пробовал всё. Время жизни сессий немного улучшилось. WhatsApp обнаруживал автоматизированный браузер и завершал сессии на стороне сервера.
Почему WhatsApp обнаруживает browser-use: цепочка fingerprinting
browser-use работает на Playwright, а Playwright запускает Chrome в headless-режиме. WhatsApp снимает fingerprint браузерного слоя и помечает именно headless-сессии. Обнаружение нацелено на среду выполнения, а не на содержимое сообщений.
Обнаружение работает сразу на нескольких уровнях. Первый: navigator.webdriver. В headless-сессии Playwright это JavaScript-свойство по умолчанию равно true. WhatsApp Web его читает. Браузер реального пользователя возвращает false. Это единственное свойство является надёжным и дешёвым для проверки bot-сигналом, который WhatsApp проверяет уже много лет.
navigator.webdriver = true в headless-сессии Chrome: WhatsApp читает это свойство при подключении, и оно — один из наиболее явных сигналов автоматизированной сессии в fingerprint браузера.
Помимо этого свойства, fingerprint уходит глубже. Строка WebGL-рендерера headless-экземпляра, запущенного на облачном VPS, отличается от названия GPU-драйвера на потребительском ноутбуке. Временны́е паттерны соединения тоже различаются. LLM-агент, навигирующий по интерфейсу WhatsApp Web, производит задержки с машинной регулярностью на уровне миллисекунд, выбирая контакт ровно за то же число миллисекунд каждый раз. Поведение скролла, тайминг событий кликов, последовательности взаимодействия с DOM — эти паттерны используются в обнаружении ботов годами на множестве платформ, и WhatsApp не исключение.
browser-use можно запустить в режиме без headless со stealth-плагинами для маскировки fingerprint-сигналов. Я пробовал оба варианта. Не-headless-режим на облачном сервере требует Xvfb — эмулятора виртуального дисплея. Это добавляет ещё один сервис для поддержки и ещё одну точку отказа. Stealth-плагины закрывают некоторые свойства, но не все. Обновления обнаружения WhatsApp выходят быстрее, чем плагины сообщества: подходы, работавшие в начале 2025 года, были частично детектированы снова к середине 2025-го — судя по отчётам в issues browser-use и Playwright на GitHub.
Можно также прочитать руководство Whapi.Cloud по предотвращению блокировок, чтобы понять, что именно отслеживает серверная система WhatsApp. Там паттерны связаны с поведением новых номеров и резкими скачками объёмов, а не только с fingerprints. Но применительно к browser-use проблема fingerprinting фундаментальна, и устранять её на уровне приложения — проигрышная игра.
Цепочка такова: browser-use запускает Playwright; WhatsApp обнаруживает Playwright; ваш аккаунт исчезает. Чистого обхода нет, потому что проблема существует на уровне инфраструктуры. WhatsApp снимает fingerprint с headless Chrome иначе, чем с браузеров реальных пользователей, — и блокирует его. Патч navigator.webdriver смещает вас на один шаг ниже в списке обнаружения, но не выводит из него.
Итоги 30 дней: 12 блокировок, 47 сломанных сессий, ни одного стабильного пайплайна
За 30 дней работы browser-use против WhatsApp Web в продакшне я зафиксировал 12 блокировок аккаунта, 47 сессий, потребовавших ручного восстановления, и примерно 23 часа времени на обслуживание. Лог начинается оптимистично.
Неделя 1 прошла без происшествий. Сессии истекли дважды, оба раза я сканировал QR с телефона, доставлено около 200 сообщений. Я думал, что у меня есть нечто рабочее с небольшими неудобствами.
Неделя 2 началась с первой блокировки. Номер телефона, который я использовал, получил временное ограничение от WhatsApp. Причина не указана — только уведомление о нарушении Условий использования. Ограничение сняли через 24 часа. Я подключил сервис резидентных прокси и снизил темп отправки.
Прокси помогали пять дней. Затем вторая блокировка — на этот раз на 48 часов. Я зарегистрировал третий номер. Сбои сессий стали ежедневными, иногда по несколько раз в день; прокси вносили задержки соединения, которые сбивали с толку состояние браузерной сессии. Каждое утро первым делом я проверял логи VPS.
День 21: третья блокировка за одну неделю. У меня уже был зарегистрирован запасной номер телефона — к тому моменту я ждал каждую блокировку до того, как она случится.
К четвёртой неделе я построил то, что назвал «session manager». На практике это был: цикл повторных попыток с экспоненциальным откатом, эндпойнт /health, Telegram-бот для оповещений о падении сессии и инструкция по восстановлению, к которой я постоянно обращался, потому что каждая блокировка требовала особой последовательности повторной аутентификации, чтобы не спровоцировать следующую. Автоматизация теперь требовала активного мониторинга для работы.
Финальный сбой произошёл в 2 часа ночи во время пакетной рассылки подтверждений отправки. Сорок покупателей ждали статусы своих заказов. Сессия упала, цикл повторов исчерпал все попытки, не отправив ни одного сообщения, а мой Telegram-алерт сработал, пока я спал. Я проснулся с пустой очередью и 40 недоставленными уведомлениями.
Двадцать три часа обслуживания за 30 дней — это не звучит катастрофой, пока не замечаешь, что всё это распределено исключительно по ночам и выходным. Сессии ломаются не по расписанию. Они ломаются во время кампаний, в пиковые часы заказов и пока вы спите.
Как на самом деле выглядит код browser-use для WhatsApp в продакшне
Вот конфигурация browser-use для WhatsApp, которую я запускал в продакшне. Тридцать одна строка для попытки отправить одно сообщение, причём блок обработки ошибок длиннее самой логики отправки.
Это основная функция отправки. Она повторно использует сохранённый контекст браузера, чтобы пропустить QR-сканирование при перезапуске.
import asyncio
import os
from browser_use import Agent, Browser, BrowserConfig
from browser_use.browser.context import BrowserContextConfig
from langchain_openai import ChatOpenAI
SESSION_FILE = "/tmp/whatsapp_session.json"
async def send_whatsapp_message(phone: str, message: str) -> bool:
browser = Browser(
config=BrowserConfig(
headless=True, # headless = detectable by WhatsApp
chrome_instance_path="/usr/bin/chromium",
)
)
context_config = BrowserContextConfig(
save_storage_state=SESSION_FILE,
storage_state=SESSION_FILE if os.path.exists(SESSION_FILE) else None,
)
agent = Agent(
task=(
f"Open https://web.whatsapp.com. "
f"If a QR code is visible, raise an error -- session expired. "
f"Search for contact {phone}, open the chat, "
f"type '{message}', and click Send."
),
llm=ChatOpenAI(model="gpt-4o"),
browser=browser,
browser_context_config=context_config,
)
try:
await agent.run(max_steps=20)
return True
except Exception as e:
os.remove(SESSION_FILE) # force re-auth on next run
raise RuntimeError(f"Send failed: {e}") from e
finally:
await browser.close()
Эта функция обрабатывает ровно один счастливый путь. Она не обрабатывает CAPTCHA-вызовы, изменения в DOM-разметке WhatsApp Web после обновлений, ответы rate-limit от сервера, ситуацию, когда агент выбирает не тот контакт, или ситуацию, когда LLM исчерпывает шаги, не найдя чат.
Обёртка восстановления сессии вокруг этой функции добавляет ещё 15 строк логики повторов, и всё равно не может восстановиться после CAPTCHA-вызова или жёсткой блокировки аккаунта без человека, который физически возьмёт телефон.
К концу третьей недели продакшн-конфигурация включала ещё: пинг /health каждые пять минут, Telegram-алерт при сбое, экспоненциальный откат на повторах, очередь недоставленных сообщений и скрипт восстановления для переинициализации сессии после блокировки. Вот реальный масштаб «использования browser-use для WhatsApp» в продакшн-режиме.
Чистая Python-конфигурация для WhatsApp без этих лесов выглядит совершенно иначе. Руководство по Python WhatsApp-боту охватывает весь стек — от подключения номера до доставки сообщений.
Когда browser-use действительно имеет смысл (но не для WhatsApp)
browser-use хорош для браузерной автоматизации. WhatsApp — одна из худших поверхностей для его применения, потому что WhatsApp активно обнаруживает именно ту среду выполнения, на которую опирается browser-use.
Случаи, когда browser-use работает хорошо:
-
Веб-скрапинг сайтов без API: извлечение структурированных данных с публичных страниц, не предоставляющих программный доступ и не запускающих активное обнаружение ботов.
-
Автоматизация внутренних инструментов: заполнение корпоративных форм в устаревших CRM или внутренних порталах, когда целевая система не обнаруживает автоматизацию. Многошаговые рабочие процессы с переменными макетами хорошо подходят для этого.
-
Задачи исследования и синтеза с нескольких страниц, где ИИ-агент обходит несколько сайтов, собирает данные и формирует сводный результат. Ни одно отдельное API не покрывает это; браузер — единственный доступный интерфейс.
Если WhatsApp не в URL — browser-use, скорее всего, разумный выбор.
После третьей блокировки за две недели я перешёл на настоящее API
После третьей блокировки за две недели я прекратил латать браузерный слой и стал искать другую модель подключения. Whapi.Cloud использует сокеты веб-сессии вместо браузера — без headless Chrome-процесса и без обнаруживаемого fingerprint на вашей стороне.
Модель подключения — ключевое отличие. browser-use запускает Chrome-процесс, навигирует по WhatsApp Web как настоящий браузер и пытается поддерживать сессию при перезапусках. Whapi.Cloud управляет соединением на уровне протокола в управляемой инфраструктуре. Ваш код делает REST-вызов. Нечего снимать fingerprint с браузера, потому что на вашей стороне никакой браузер не работает.
Вот код, который заменил мою 31-строчную функцию browser-use. Отправляет то же сообщение тому же номеру, решает тот же сценарий — в 10 строк:
import requests
WHAPI_TOKEN = "YOUR_TOKEN_HERE"
def send_whatsapp(phone: str, message: str) -> dict:
"""Send a WhatsApp text message via Whapi.Cloud REST API."""
response = requests.post(
"https://gate.whapi.cloud/messages/text",
headers={"Authorization": f"Bearer {WHAPI_TOKEN}"},
json={"to": f"{phone}@s.whatsapp.net", "body": message},
)
response.raise_for_status()
return response.json()
# Usage -- returns message ID and delivery confirmation
result = send_whatsapp("15551234567", "Your order has shipped!")
print(result)
Никакого браузер-процесса для управления. Никаких файлов сессии. Никакого QR-кода для сканирования при каждом перезапуске сервера. Номер был подключён один раз через QR-сканирование в панели Whapi.Cloud, и API работает с тех пор. Вебхуки доставляют входящие сообщения в реальном времени без поллинга. Полная документация API покрывает каждый эндпойнт с примерами кода на Python, PHP и Node.js.
За три недели после перехода WhatsApp Web выпустил обновление интерфейса, которое сломало несколько конфигураций браузерной автоматизации, обсуждавшихся в issues на GitHub. Соединение Whapi.Cloud продолжало работать без каких-либо изменений с моей стороны. Команда отслеживает изменения протокола WhatsApp и непрерывно выпускает обновления. Когда WhatsApp меняет что-то под капотом, их инфраструктура это поглощает. Когда вы запускаете браузерную автоматизацию, каждое обновление WhatsApp Web становится вашим аварийным случаем.
Одно и то же соединение Whapi.Cloud работало три недели без единой блокировки, падения сессии или ночного алерта. Вот полная история обслуживания — ноль инцидентов в том же временном окне, которое дало 12 блокировок и 47 сломанных сессий на конфигурации с browser-use. Управляемая API-инфраструктура обеспечивает гарантии аптайма. История надёжности браузерной автоматизации звучит так: вчера работало.
Реальная стоимость «бесплатной» автоматизации WhatsApp через browser-use
browser-use бесплатно скачать. Запускать его для WhatsApp в продакшне уже со второго месяца обходится дороже, чем API-подписка. Вот реальная разбивка.
| Статья расходов | Конфигурация browser-use (ежемесячная оценка) | API Whapi.Cloud |
|---|---|---|
| Сервер / VPS | $10–20/мес. (headless Chrome требует 2+ ГБ RAM) | Включено (управляемая инфраструктура) |
| Ротация прокси | $15–40/мес. (резидентные прокси снижают риск обнаружения) | Не требуется |
| Вызовы LLM API | $30–80/мес. (browser-use вызывает GPT-4o на каждом шаге навигации) | Не требуется |
| Замена номеров | $5–15/мес. (блокировки расходуют номера телефонов) | Используйте существующий номер |
| Время разработчика на обслуживание | 20–30 ч/мес.; по любой ставке, которую вы назначите | Почти ноль после первоначальной настройки |
| Подписка Whapi.Cloud | Не применимо | ~$40/мес. за номер (фиксированная ставка, без оплаты за сообщение) |
| Итого на 2-й месяц (только деньги) | $60–155+ (без учёта часов на обслуживание) | ~$40/мес., стабильно |
Расходы на LLM — то, что удивляет большинство людей. browser-use вызывает GPT-4o для интерпретации интерфейса WhatsApp Web на каждом шаге: прочитать DOM, найти контакт, перейти в чат, набрать сообщение, нажать «Отправить», проверить доставку. Каждая отправка сообщения включает несколько вызовов инференса, а стоимость GPT-4o быстро накапливается при любом реальном объёме.
Конфигурация с browser-use обошлась мне примерно в $280 за два месяца наличными (без учёта 23 часов обслуживания) против $40/мес. подписки Whapi.Cloud, которая её заменила.
При очень малых объёмах (несколько десятков сообщений в месяц, просто тестирование концепции локально) browser-use дешевле по деньгам. При продакшн-объёмах или в любом сценарии, где недоставленное сообщение влияет на реального пользователя, экономика меняется до конца первого месяца.
Фрейм «бесплатно против платно» — неверная оптика для автоматизации WhatsApp. Настоящий вопрос: хотите ли вы рабочий пайплайн сообщений или проект по обслуживанию? Это разные продукты с разными затратами, и browser-use поставляет второй вариант при применении к WhatsApp.
Если вы попали сюда, погуглив «browser-use WhatsApp»
Вы в той же точке принятия решения, в которой я был пять недель назад. Путь браузерной автоматизации работает для демо. В продакшне под нагрузкой режим отказа — это заблокированный аккаунт с очередью недоставленных сообщений.
Репозиторий browser-use — по-настоящему интересное ПО, и демо убедительны. Настоящая проблема — это несовпадение: надёжная автоматизация WhatsApp требует поддержания аутентифицированного соединения, проходящего проверки fingerprinting. browser-use решает управление браузером. Система WhatsApp закрывает его на уровне аутентификации.
Если ваша цель — отправлять сообщения WhatsApp из кода (подтверждения заказов, уведомления, ответы чатботов, всё, на что рассчитывают пользователи), вам нужен слой подключения, который управляет сессией WhatsApp за вас. Подключите номер один раз через QR-сканирование, затем используйте REST API. 10-строчная версия работает; 150-строчная ломается в 2 ночи.
В 2 часа ночи с мёртвой очередью сессии и 40 покупателями, ожидающими обновлений заказов, — вот как выглядит обслуживание browser-use в продакшне. Настоящая продуктовая работа начинается после того, как вы перестаёте управлять слоем подключения.









