При выполнении веб-задач Agent сбои чаще всего возникают в четырех областях: поиск элементов, ожидания и тайм-ауты, сохранение состояния и блокировки со стороны среды. Идемпотентные шаги, управляемые повторы, сохранение состояния и изоляция среды для каждой задачи заметно стабилизируют процент успешных выполнений.
На старте веб-автоматизации подход обычно кажется простым: описать процесс и запустить скрипт. Логика выглядит правильной, но задачи все равно время от времени завершаются с ошибкой, а состояние аккаунтов иногда ведет себя необычно. Первая реакция — искать проблему в коде, однако при более глубокой проверке причины обычно сводятся к четырем областям.

Изменение страницы ломает поиск элементов
Большинство скриптов находят элементы с помощью селекторов. Если селектор жестко задан, почти любое изменение страницы может сделать его нерабочим: у кнопки меняется имя класса, в тексте меняется одно слово, блок переходит с серверного рендеринга на асинхронную загрузку или элемент помещают в новый контейнер. При A/B-тесте одна и та же страница может даже иметь разную структуру для разных аккаунтов.
Обычно это проявляется так: элемент не находится, клик попадает не туда или нажимается одноименный элемент управления в другом месте. Такой сбой не связан с колебаниями сети, поэтому несколько повторов его не исправят.
Практичный подход — меньше зависеть от абсолютных путей. Лучше использовать атрибуты доступности, стабильные бизнес-ID или относительные связи между элементами; для одного типа страниц стоит подготовить резервные селекторы и автоматически переходить на них, если основной перестал работать. Если на странице есть iframe или Shadow DOM, сначала нужно переключиться в правильный контекст, иначе поиск не сработает.
Ожидания и тайм-ауты выбраны в неправильном диапазоне
Если время ожидания слишком короткое, элемент могут признать недоступным до завершения рендеринга, и это выглядит как ошибка скрипта. Если оно слишком длинное, время выполнения одной задачи неоправданно растет, пропускная способность падает, а длинные тайм-ауты могут скрывать настоящую ошибку.
Явные ожидания надежнее фиксированного sleep: нужно ждать конкретного условия, например появления целевого элемента, ответа на запрос или исчезновения индикатора загрузки. Бюджеты тайм-аутов следует задавать по уровням — отдельно для одного шага, страницы и всей задачи — и постепенно сужать, а не использовать одно значение везде.
Также важно различать ожидание готовности страницы к работе и ожидание формирования бизнес-результата. В первом случае обычно достаточно готовности DOM; во втором может потребоваться callback API или изменение текста статуса на странице. Если ждать неправильный сигнал, операция может выглядеть успешной, хотя данные фактически не записались.
Прогресс теряется в середине многошаговой задачи
Регистрация, оформление заказа или публикация легко включают больше десяти шагов. Если процесс прерывается на середине из-за тайм-аута, сбоя браузера или перезапуска хоста, а состояние хранится только в памяти, следующий запуск либо начинается сначала, либо повторно отправляет предыдущий шаг.
Последствия повторного выполнения иногда сложнее диагностировать, чем обычный сбой: одна и та же операция выполняется дважды, во внешней системе появляется лишняя запись, а ее источник трудно отследить.
Решение — дать каждому шагу точку сохранения. После завершения каждого шага записывать прогресс в постоянное хранилище вместе с уникальным идентификатором задачи; после перезапуска продолжать с последней успешно завершенной точки. Сложный фреймворк для этого не нужен — достаточно файла или одной записи состояния.
Блокировка со стороны среды выглядит как ошибка кода
Первые три категории проблем возникают внутри задачи, но еще одна приходит со стороны среды. Сайт может учитывать характеристики браузера, поведение доступа и сетевое происхождение трафика. Если доступ кажется подозрительным, сайт может вернуть страницу проверки, пустой контент или просто тайм-аут. В журнале задачи это почти неотличимо от ошибки выполнения.
Распространенные причины:
- География выходного IP, часовой пояс и язык не совпадают
- Все задачи отправляют запросы из одной браузерной среды, и плотность запросов в единицу времени заметно выше, чем у реальных пользователей
- Среда часто меняется или аккаунт многократно выполняет повторный вход
Четыре меры, повышающие процент успешных выполнений
- Сделать каждый шаг идемпотентным. Перед выполнением проверять, выполнено ли предварительное условие, чтобы повтор действия не создавал дополнительных побочных эффектов. Операции чтения идемпотентны по своей природе; для операций записи нужен уникальный идентификатор или ключ дедупликации.
- Классифицировать сбои. Временные проблемы — элемент еще не отрендерился, сеть нестабильна, API вернул 5xx — можно повторять с backoff. Детерминированные ошибки — ограничение аккаунта, неверные параметры или отсутствие целевого ресурса — не исчезнут от новых попыток; их лучше завершать, чтобы они не занимали лимит параллелизма.
- Регулярно сохранять состояние. Хранить прогресс, промежуточные результаты и текущий шаг, чтобы после перезапуска задача продолжалась с места остановки, а не с первого шага.
- Изолировать среду выполнения для каждой задачи. Каждому аккаунту или задаче нужна отдельная браузерная среда, в которой Cookies и локальное хранилище не разделяются, характеристики fingerprint разумно отличаются, а часовой пояс и язык соответствуют региону выходного IP.
Четвертая мера особенно важна при росте масштаба. Когда десятки или сотни задач выполняются параллельно, слой среды задает верхнюю границу стабильности и определяет масштаб последствий при возникновении проблемы. В таких сценариях PurpleMark позволяет создавать изолированные среды по запросу и массово освобождать их, предоставляя каждому аккаунту собственную среду, чтобы состояния разных задач не влияли друг на друга.
Этот материал предназначен исключительно для технических исследований и обмена практиками разработки. Используйте соответствующие технологии законно и с соблюдением требований, а также следуйте условиям использования целевой платформы.


